前端

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

2018-08-06  本文已影响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即可。

上一篇下一篇

猜你喜欢

热点阅读