ChatGPT解决这个技术问题 Extra ChatGPT

How to direct vue-cli to put built project files in different directories?

Maybe 8-9 months ago I created a Webpacked Vue.js project with vue-cli and was able to modify /build/webpack.dev.conf.js to have it put the "compiled" index.html and JavaScript / CSS files in the right folders in my Flask app when I run npm run build.

I am now showing someone else how to create a Vue.js / Flask app and I see that the way vue-cli works seems to have changed, so that I no longer have access to the /build/ folder.

I read the docs and they seemed to say that it now abstracts away the Webpack config ("Since @vue/cli-service abstracts away the webpack config..."), but that if I want to see Webpack's config options, I can do vue inspect > output.js. I did that and don't see the entries in there that I changed when I did this eight months ago:

/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',

It looks like the vue build command-line command can accept an argument that allows you to specify the output directory, but I need to specify two different directories: one for the HTML file (which should live in Flask's /templates/ folder), and another for the JavaScript / CSS code (which should go in Flask's /static/ folder).

What exactly are you looking for in output.js file? I just ran this command and there is entry and output properties that refer to the directories you are trying to change. Have you tried to override them in vue.config.js as the documentation says?
@oniondomes I've updated my question to include the files and lines I changed last time. As I mention in the question (added maybe 10-20 minutes ago so maybe you didn't see it), I want to output the HTML file to one directory and the JavaScript / CSS to another directory.
does anyone now if it's possible to pass args in the npm run command? for example: npm run build --output-path /my-path ?
@DAG Yes, see this SO answer: stackoverflow.com/a/14404223/4115031

p
peterhartree

I just had to do this for a new project using the latest Vue-CLI and it was pretty simple: I just needed to have a file called vue.config.js at the top-level of my Vue project and within it I needed the following code:

const path = require("path");

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

Warning: Vue-CLI will delete the contents of whatever folders you specify to use for its output. To get around this, I created the "SPA" folders within my templates/ and static/ directories.

Note also that the assetsDir is specified relative to the outputDir.


Awesome! This is very usefull! Help me with Django + Vue project.
I use .env instead, so outputDir: process.env.OUTPUT_DIR,; so that I can add .env to .gitignore and dotenv is already enabled by default by Vue CLI.
why not simply outputDir: '../backend/templates/SPA'? it works for me
@Konrad Good question; I don't know! I think I copied the code from some official guide.
b
bvj

Per the related vuejs guide

WARNING Some webpack options are set based on values in vue.config.js and should not be mutated directly. For example, instead of modifying output.path, you should use the outputDir option in vue.config.js; instead of modifying output.publicPath, you should use the baseUrl option in vue.config.js. This is because the values in vue.config.js will be used in multiple places inside the config to ensure everything works properly together.

And the related vuejs config reference

TIP Always use outputDir instead of modifying webpack output.path.

Here's an example vue.config.js that I just verified using vue-cli-service @ 3.0.0-rc.2

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'
    }
  }
}

v
vess

By default, production files are built into the /dist/ subfolder of your Vue project and they are supposed to be deployed in the root folder of your server ("/"). Hence you will have to copy them to root in order to access the project from your browser. Since this is not always convenient, you may wish to build them for deployment in a subfolder of root e.g. /subdir/vue_project/dist/.

In this case, follow the advice at https://cli.vuejs.org/config/#publicpath to redirect vue-cli to build the project files for this subfolder. To do this, please execute vue ui, then open the cli 3.3+ UI Configuration window at localhost:8000 then change the default value of publicPath to /subdir/vue_project/dist/ and Save changes.

If you wish to go back to development (serve), do not forget to set publicPath back to / before executing serve and accessing localhost:8080.


Easiest solution, generates vue.config.js for me. Thanks!
E
Edward Bonnett

I struggled with this yesterday myself, but managed to crack it in the end by using part of oniondomes answer and some of the new documentation:

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')
                        }
                    ];
                });
        }
    }
}

The key difference is the chainwebpack section - this allowed you to override any existing configs for plugins referenced. The other answer is adding another html-webpack-plugin which I believe is causing it to throw an error.

I originally had the configs as objects, but this caused issues when trying to run in dev mode. By changing them to functions you can specify that this only occurs when building in production mode.

At any point you can see the webpack config generated with these overrides by running the following from the console

vue inspect > output.js

The issue I needed to fix was specific to an C# MVC project - needing to output to a cshtml page. I'll leave my solution to that here for anybody that needs it.

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' },
                ]});
        }
    }
}

a
asanchez

With newer versions of Vue.js, you just have to set the proper publicPath in your the file vue.config.js on the root folder:

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

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

More infos: https://cli.vuejs.org/guide/deployment.html#general-guidelines


o
oniondomes

To be honest I don't see what problem you're having since you have seen the docs and pointed directly to the right section of it. I just created a new vue.js project using vue-cli 3.0, created vue.config.js file in project's root directory and looking at output.js (created automatically with vue inspect > output.js) I have written the following:

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'),
      }),
    ],
  },
};

Now when I run build script my files goes to the another-dir folder and html code is taken from test.html. I guess following this method you can reconfigure your project according to your need.

Hope I did understand you question right and didn't waste everyone's time.

EDIT: this seems to be placing files as you want, but for some reason HtmlWebpackPlugin happens to create dist/ folder and output .html file twice in both /dist and /templates. To this one I couldn't find a solution yet.


Like I said in my response to your comment, the issue is that I need to have the HTML file go to my /templates/ folder and my JavaScript / CSS go to the /static/ folder. From what I can tell, the config options do not allow you to specify that the files should be split into separate output folders like that.
Thanks for this, this is very close to what I need. I just need one change: my Vue.js project folder is within my Python server project folder, not the other way around (as you have it here). I'm looking up how to make that change myself but you may know off the top of your head.
You can do it the same way you've done it before. Just go to the upper directories as long as you want like this: '../../your-folder'
And I have to warn you that this situation is an uncharted territory for me, so there can be some hidden problems with my solution. Also worth mentioning is that vue-cli 3.0 is still in the beta and it could happen to be not as stable as you want. You can still use the previous version if you wish.
The output part of the code is working (all files are being put in my Flask app's "static" folder) but the HtmlWebpackPlugin part is throwing an error for me: TypeError: Cannot read property 'source' of undefined

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now