美文网首页前端
laravel-mix提取Vue组件中的CSS样式

laravel-mix提取Vue组件中的CSS样式

作者: 落痕無情 | 来源:发表于2018-08-06 15:55 被阅读547次

    对于想在 Laravel 项目中提取 Vue 组件中的 CSS 样式到一个文件中,laravel-mix 的文档写得很简单,只需要添加一行配置项即可:

    mix.options({
        extractVueStyles: true
    });
    

    然而在实际开发中,我还是遇到了问题。

    如果你的Vue组件是全局注册并且是同步加载的:

    Vue.component('example', require('./components/Example.vue'));
    

    那么配置好 extractVueStyles: true 就基本可以了。只不过如果你在某一个组件的 <script> 标签中通过 import 的方式引入了CSS样式,那么这部分样式最终还是会注入到 html 页面的 <style> 标签中。

    比如我项目中用到了一个社交分享组件,最终 client.css 里面的内容还是无法单独提取出来:

    import Share from "vue-social-share";
    import "vue-social-share/dist/client.css";
    export default {
      components: {
        Share
      },
      data() {
        return {
          shareConfig: {
            sites: ["qq", "qzone", "weibo"]
          }
        };
      }
    };
    

    这只是遇到的第一个问题。其次,由于为了减少白屏时间,我在项目中使用了异步组件的加载方式,这下子上面的方法几乎就行不通了。

    Vue.component('example', () => import('./components/Example.vue'));
    

    这里多说一句,使用异步组件必须安装 babel-plugin-syntax-dynamic-import 插件,然后在项目根路径下新建一个 .babelrc 文件添加配置:

    {
        "plugins": ["syntax-dynamic-import"]
    }
    

    其实,这两个CSS提取不完整的问题的根本原理是一致的,最终我还是在 vue-cli 的源码中找到了 ExtractTextPlugin 插件,看一下 allChunks 的定义就很容易明白了:

    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[contenthash:8].css'),
      // Setting the following option to `false` will not extract CSS from codesplit chunks.
      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
      // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 
      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
      allChunks: true,
    }),
    

    原来是 laravel-mix 设计本身的问题,没有配置这个 allChunks,所以必须需要通过修改源码的方式来修复。

    找到 node_modules\laravel-mix\src\components\Vue.js 文件中的 extractPlugin 方法,传递一个对象给构造函数,并加上一条 allChunks: true 直接搞定!

    extractPlugin() {
      if (typeof Config.extractVueStyles === 'string') {
          // return new ExtractTextPlugin(this.extractFilePath());
          return new ExtractTextPlugin({
              filename: this.extractFilePath(),
              allChunks: true,
          });
      }
      // ...
    

    注:一般选择在生产环境下提取CSS即可。

    相关文章

      网友评论

        本文标题:laravel-mix提取Vue组件中的CSS样式

        本文链接:https://www.haomeiwen.com/subject/yprgvftx.html