最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vue.js CLI 3 - how can I create a vendor bundle for CSSSass? - Stack Overflow

programmeradmin0浏览0评论

Using @vue/cli 3.x and I have modified my vue.config.js slightly. I want to have separate CSS files such as app.css and vendor.css (transpiled from Sass) - similar to how its configured to treat the JavaScript. I am unsure how to set the proper config to achieve this. Am I loading my files incorrectly? Missing the mark entirely?

// vue.config.js
module.exports = {
  // [...]
  configureWebpack: {
    optimization: {
      splitChunks: {
        cacheGroups: {
          shared: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendor',
            enforce: true,
            chunks: 'all',
          }
        }
      }
    }
  }
};

My where build results in...

dist
├── css
|   └── app.css
├── js
|   ├── app.js
|   └── vendor.js

app.css includes all I've imported through my node_modules. My style import is as follows in my main App.vue ponent...

<style lang="scss">
  @import '../node_modules/minireset.css/minireset.sass';
</style>

// [...]

My desired result is the following structure, where the "vendor" CSS/Sass is extracted out...

dist
├── css
|   ├── app.css
|   └── vendor.css
├── js
|   ├── app.js
|   └── vendor.js

I've looked into the MiniCssExtractPlugin where the first sentences states the following...

This plugin extracts CSS into separate files

But I've found no examples of how to do it idiomatically in the Vue.js ecosystem. I've also tried to add the following to my vue.config.js, but nothing seems to take effect...

module.exports = {
  // [...]
  css: {
    extract: {
      filename: 'css/[name].css',
      chunkFilename: 'css/[name].css',
    },
  },
};

I've also found what should have been a home run explanation in the Vue SSR Guide | CSS Management, but it uses webpack.optimize.CommonsChunkPlugin which has been deprecated in favor of webpack.optimize. SplitChunksPlugin, throwing a build error...

Error: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.

Using @vue/cli 3.x and I have modified my vue.config.js slightly. I want to have separate CSS files such as app.css and vendor.css (transpiled from Sass) - similar to how its configured to treat the JavaScript. I am unsure how to set the proper config to achieve this. Am I loading my files incorrectly? Missing the mark entirely?

// vue.config.js
module.exports = {
  // [...]
  configureWebpack: {
    optimization: {
      splitChunks: {
        cacheGroups: {
          shared: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendor',
            enforce: true,
            chunks: 'all',
          }
        }
      }
    }
  }
};

My where build results in...

dist
├── css
|   └── app.css
├── js
|   ├── app.js
|   └── vendor.js

app.css includes all I've imported through my node_modules. My style import is as follows in my main App.vue ponent...

<style lang="scss">
  @import '../node_modules/minireset.css/minireset.sass';
</style>

// [...]

My desired result is the following structure, where the "vendor" CSS/Sass is extracted out...

dist
├── css
|   ├── app.css
|   └── vendor.css
├── js
|   ├── app.js
|   └── vendor.js

I've looked into the MiniCssExtractPlugin where the first sentences states the following...

This plugin extracts CSS into separate files

But I've found no examples of how to do it idiomatically in the Vue.js ecosystem. I've also tried to add the following to my vue.config.js, but nothing seems to take effect...

module.exports = {
  // [...]
  css: {
    extract: {
      filename: 'css/[name].css',
      chunkFilename: 'css/[name].css',
    },
  },
};

I've also found what should have been a home run explanation in the Vue SSR Guide | CSS Management, but it uses webpack.optimize.CommonsChunkPlugin which has been deprecated in favor of webpack.optimize. SplitChunksPlugin, throwing a build error...

Error: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.

Share Improve this question edited Dec 31, 2018 at 20:25 Rockey 4016 silver badges18 bronze badges asked Dec 28, 2018 at 22:29 scniroscniro 17k8 gold badges66 silver badges107 bronze badges 1
  • 1 Though this question is answered, I largely consider the current solution a workaround. I've opened an issue against the project which hopefully will gain some attention in the future github./vuejs/vue-cli/issues/3252 – scniro Commented Jan 8, 2019 at 15:24
Add a ment  | 

3 Answers 3

Reset to default 3 +100

The vue.config.js also lets you use a chainWebpack method. It might be preferable because it allows you to modify the vue-cli config. Using configureWebpack overwrites the default config entirely, which might be part of the problem in regards to getting yours to work with Sass.

This config is for pure CSS only, but is fairly similar to what you have.

Just tried this with some Sass embedded into some style blocks, and it breaks up the vendor css from the app css.

module.exports = {
    chainWebpack(config) {
        config
            .output.chunkFilename('[name].bundle.js').end()
            .optimization.splitChunks({
                cacheGroups: {
                    vendorStyles: {
                        name: 'vendor',
                        test(module) {
                            return (
                                /node_modules/.test(module.context) &&
                                // do not externalize if the request is a CSS file
                                !/\.css$/.test(module.request)
                            );
                        },
                        chunks: 'all',
                        enforce: true
                    }
                }
            });
    }
};

Update

It's also necessary to pull out your @import '../node_modules/minireset.css/minireset.sass'; and other import statements out of the style block and put it in the script block of your vue ponent:

// your ponent file
<script>
    import "minireset.css/minireset.sass";
    // rest of script
</script>

The file will still be imported and used in your style block below.

My exports include a vendor.[hash].css and an app.[hash].css file. The app file has the content of the style blocks. Since I kept my test app simple and to your use case, the vendor file contains only the style info from minireset:

// vendor.[hash].css
/*! minireset.css v0.0.3 | MIT License | github./jgthms/minireset.css */blockquote,body,dd,dl,dt,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,html,iframe,legend,li,ol,p,pre,textarea,ul{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:400}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}audio,embed,iframe,img,object,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0;text-align:left}

Git repo of vue app here. The import of the sass file is in HelloWorld.vue.

You can add the MiniCssExtractPlugin to your webpack config (per the docs):

// vue.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  // [...]
  configureWebpack: {
    plugins: [
      new MiniCssExtractPlugin({
        filename: '[name].css'
      })
    ],
    optimization: {
      splitChunks: {
        cacheGroups: {
          shared: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendor',
            enforce: true,
            chunks: 'all',
          }
        }
      }
    }
  }
};

However, this may not work with single file ponents. In order to get that working you might have to use vue-loader@next

I have used once this plugin and I believe it does what you want to achieve: https://github./teamable-software/css-chunks-html-webpack-plugin

发布评论

评论列表(0)

  1. 暂无评论