如何指定vue-cli将构建后的项目文件放入不同的目录?

65

大约8-9个月前,我使用vue-cli创建了一个基于Vue.js的Webpack项目,并能够修改/build/webpack.dev.conf.js,以便在运行npm run build时将“已编译”的index.html和JavaScript / CSS文件放入我的Flask应用程序中的正确文件夹。

现在我正在向别人展示如何创建Vue.js / Flask应用程序,我发现vue-cli的工作方式似乎已经改变,以至于我不再可以访问/build/文件夹了。

我阅读了文档并且他们似乎说现在它抽象出了Webpack配置(“由于@vue/cli-service抽象出了webpack配置...”),但是如果我想查看Webpack的配置选项,我可以使用vue inspect > output.js。我这样做了,但是我没有看到我八个月前更改过的条目:

/build/webpack.prod.conf.js:

new HtmlWebpackPlugin({
  filename: process.env.NODE_ENV === 'testing'
-    ? 'index.html'
+    ? 'app.html'
    : config.build.index,
-  template: 'index.html',
+  template: 'app.html',

/build/webpack.dev.conf.js

new HtmlWebpackPlugin({
-   filename: 'index.html',
-   template: 'index.html',
+   filename: 'app.html',
+   template: 'app.html',

/config/index.js

module.exports = {
  build: {
    env: require('./prod.env'),
-    index: path.resolve(__dirname, '../dist/index.html'),
-    assetsRoot: path.resolve(__dirname, '../dist'),
-    assetsSubDirectory: 'static',
-    assetsPublicPath: '/',
+    index: path.resolve(__dirname, '../../server/templates/app.html'),
+    assetsRoot: path.resolve(__dirname, '../../server/static/app'),
+    assetsSubDirectory: '',
+    assetsPublicPath: '/static/app',
看起来,vue build 命令行命令可以接受一个参数,允许您指定输出目录,但是我需要指定两个不同的目录:一个用于 HTML 文件(应该位于 Flask 的 /templates/ 文件夹中),另一个用于 JavaScript / CSS 代码(应该位于 Flask 的 /static/ 文件夹中)。

你在 output.js 文件中具体要寻找什么?我刚刚运行了这个命令,发现有 entryoutput 属性,它们指向你想要更改的目录。你是否尝试按照文档所说,在 vue.config.js 中覆盖它们呢? - oniondomes
@oniondomes 我已经更新了我的问题,包括上次更改的文件和行。正如我在问题中提到的(可能是10-20分钟前添加的,所以您可能没有看到),我想将HTML文件输出到一个目录,将JavaScript / CSS输出到另一个目录。 - Nathan Wailes
有人知道在npm run命令中是否可以传递参数吗?例如:npm run build --output-path /my-path - DAG
@DAG 是的,请参考这个SO答案:https://dev59.com/PGgu5IYBdhLWcg3wGTad#14404223 - Nathan Wailes
6个回答

74
我最近在一个新项目中使用最新的Vue-CLI,需要做这个事情,而且非常简单:我只需要在Vue项目的顶层拥有一个名为vue.config.js的文件,并在其中添加以下代码即可:
const path = require("path");

module.exports = {
  outputDir: path.resolve(__dirname, "../backend/templates/SPA"),
  assetsDir: "../../static/SPA"
}

警告:Vue-CLI 将删除您指定用于输出的任何文件夹的内容。 为了避免这种情况,我在我的templates/static/目录下创建了“SPA”文件夹。

还要注意,assetsDir是相对于outputDir指定的。

2023 年更新:

使用 vite.config.js 文件时,我所做的就是这个:

import { defineConfig } from 'vite'

export default defineConfig({
  (...)
  build: {
    outDir: '../backend/dist'
  }
})

太棒了!这非常有用!帮我处理Django + Vue项目。 - Serhii Zelenchuk
1
我使用 .env,所以 outputDir: process.env.OUTPUT_DIR,;这样我可以将 .env 添加到 .gitignore 中,并且 dotenv 已经被 Vue CLI 默认启用。 - Polv
2
为什么不直接使用outputDir:'../backend/templates/SPA'?这对我很有效。 - Konrad
2
@Konrad 很好的问题;我不知道!我想我是从一些官方指南中复制了代码。 - Nathan Wailes

14

根据相关的vuejs guide

警告

一些webpack选项是基于vue.config.js中的值设置的,不应直接改变。例如,不要修改output.path,而应该在vue.config.js中使用outputDir选项;不要修改output.publicPath,而应该在vue.config.js中使用baseUrl选项。这是因为vue.config.js中的值将在配置中的多个位置使用,以确保所有内容协同工作。

以及相关的vuejs配置reference

提示

始终使用outputDir,而不是修改webpack output.path。

这里是一个我刚刚使用vue-cli-service@3.0.0-rc.2验证过的示例vue.config.js

const path = require("path");

module.exports = {
  outputDir: path.resolve(__dirname, "./wwwroot/dist"),
  chainWebpack: config => {
    config.resolve.alias
      .set("@api", path.resolve(__dirname, "./src/api"));
  },

  pluginOptions: {
    quasar: {
      theme: 'mat'
    }
  }
}

10

默认情况下,Vue 项目的生产文件会被构建到项目的 /dist/ 子目录中,并且应该部署在服务器的根目录 ("/") 中。因此,您需要将它们复制到根目录以便从浏览器访问项目。由于这不总是方便,您可能希望将它们构建为部署在根目录下的一个子文件夹,例如 /subdir/vue_project/dist/

在这种情况下,请遵循https://cli.vuejs.org/config/#publicpath上的建议,来重定向vue-cli以构建该子文件夹的项目文件。为此,请执行 vue ui,然后打开 localhost:8000 上的 cli 3.3+ UI 配置窗口,接着更改 publicPath 的默认值为 /subdir/vue_project/dist/ 并保存更改。

如果您希望返回到开发模式(serve),请不要忘记在执行 serve 和访问 localhost:8080 之前将 publicPath 设置回 /


1
最简单的解决方案,为我生成vue.config.js。谢谢! - Kaspi

7

我昨天也遇到了这个问题,但最后成功解决了,方法是结合了oniondomes的答案和新文档:

const path = require('path');    
module.exports = {
    configureWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
            config.output.path = path.resolve(__dirname, './server/assets/static');
            config.output.publicPath = '../assets/static/';
            config.output.filename = '[name].js';
        }
    },
    chainWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
            config
                .plugin('html')
                .tap(args => {
                    return [
                        {
                            filename: path.resolve(__dirname, './server/templates/test.html'),
                            template: path.resolve(__dirname, './public/index.html')
                        }
                    ];
                });
        }
    }
}

关键区别在于chainwebpack部分 - 这使您可以覆盖任何现有插件的配置。 另一个答案是添加另一个html-webpack-plugin,我认为这会导致出错。
我最初将配置设置为对象,但在尝试以dev模式运行时会出现问题。 通过将它们更改为函数,您可以指定仅在生产模式下构建时才发生这种情况。
您可以随时从控制台运行以下命令来查看由这些覆盖生成的webpack配置
vue inspect > output.js

我需要解决的问题是关于一个C# MVC项目,需要输出到一个cshtml页面。我会把我的解决方案留在这里,以便任何需要的人查看。
module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'http://localhost:60263',
                changeOrigin: true
            }
        }
    },
    configureWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
            config.output.publicPath = '/dist/';
            config.entry = ['babel-polyfill', './src/main.js']
        }
    },
    chainWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
            config
                .plugin('html')
                .tap(args => {
                return [
                    { filename: '../Views/Home/Index.cshtml', template: 'public/index.html' },
                ]});
        }
    }
}

4

使用较新版本的Vue.js,您只需在根目录下的vue.config.js文件中设置正确的publicPath即可:

// vue.config.js file to be place in the root of your repository

module.exports = {
  publicPath: process.env.NODE_ENV === 'production'
    ? '/my-project/'
    : '/'
}

更多信息:https://cli.vuejs.org/guide/deployment.html#general-guidelines


3
说实话,我不明白你遇到了什么问题,因为你已经看了文档并直接指向了正确的部分。我刚刚使用 vue-cli 3.0 创建了一个新的 vue.js 项目,在项目的根目录下创建了 vue.config.js 文件,并查看了 output.js(使用 vue inspect > output.js 自动创建),我写入了以下内容:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  configureWebpack: {
    output: {
      path: path.resolve(__dirname, './server/assets/static'),
      filename: '[name].js',
      publicPath: '../assets/static/',
    },
    plugins: [
      new HtmlWebpackPlugin({
        filename: path.resolve(__dirname, './server/templates/test.html'),
        template: path.resolve(__dirname, './public/test.html'),
      }),
    ],
  },
};

现在,当我运行build脚本时,我的文件会被放置到another-dir文件夹中,并且HTML代码将来自test.html。我猜按照这种方法,您可以根据需要重新配置项目。
希望我理解您的问题,没有浪费每个人的时间。
编辑:这似乎是按您所需放置文件的方式,但由于某种原因,HtmlWebpackPlugin会在/dist/templates中分别创建dist/文件夹并输出.html文件两次。至于这一点,我还没找到解决方法。

就像我在回复你的评论中说的那样,问题是我需要将HTML文件放到/templates/文件夹中,而我的JavaScript / CSS放到/static/文件夹中。据我所知,配置选项不允许您指定文件应该分成这样的独立输出文件夹。 - Nathan Wailes
谢谢,这非常接近我需要的。我只需要一个更改:我的Vue.js项目文件夹在我的Python服务器项目文件夹内,而不是相反(就像您在此处所示)。我正在查找如何自己进行更改,但您可能一时半会儿知道如何更改。 - Nathan Wailes
你可以像以前一样做。只需像这样进入上级目录,直到你想要的位置:'../../your-folder' - oniondomes
我必须警告你,这种情况对我来说是未知的领域,所以我的解决方案可能存在一些隐藏的问题。另外值得一提的是,vue-cli 3.0仍处于测试版阶段,可能不够稳定。如果你愿意,仍然可以使用之前的版本。 - oniondomes
代码中的 output 部分正常工作(所有文件都被放置在我的 Flask 应用程序的 "static" 文件夹中),但是 HtmlWebpackPlugin 部分却出现了错误:TypeError: Cannot read property 'source' of undefined - Nathan Wailes
很难说为什么会发生这种情况。可能与这个有关:https://github.com/jantimon/html-webpack-plugin/issues/672? - oniondomes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接