webpack之公共代码抽取(四)

摘要:多页面中公用js及scss代码的抽取

一、知识点

  1. html-webpack-plugin:chunks属性。
  2. webpack.optimize.CommonsChunkPlugin:name和minChunks属性。
  3. 公用scss代码仍需要在入口文件中引用而不是在各自的scss文件中通过@import引用。
  4. 提取的公共模块文件,只是入口文件本身的业务代码变化,重新构建后提取的公共模块文件名仍保持不变,保证了浏览器的缓存作用。

二、配置代码

const webpack = require('webpack');//防止重复,抽取公共模块

plugins.push(//公共模块抽取
    new webpack.optimize.CommonsChunkPlugin({
        name: 'js/com/common', // 指定公共 模块 的名称。
        minChunks:2, //(模块必须被2个 入口chunk 共享),只要是被两个及以上的chunk引用的公共代码都会被打包到公共模块中
        //chunks: ["js/pages/PageA", "js/pages/PageB"],
        // (只使用这些 入口chunk)
    })
);

//生成html配置
plugins.push(new HtmlWebpackPlugin({
    // 生成出来的html文件名
    filename: distDir+'/html/'+ outputHtmlName + '.html',
    // 每个html的模版,这里多个页面使用同一个模版
    template:srcDir + '/html/'+ outputHtmlName + '.html',
    // 自动将引用插入body
    inject: 'body',
    title:outputHtmlName,
    // 每个html引用的js模块,也可以在这里加上vendor等公用模块
    chunks: [entryFileName,'js/com/common']//在这里增加对公共模块的引用
}));

三、完整配置

const path = require('path');
const glob = require("glob");
const HtmlWebpackPlugin = require('html-webpack-plugin'); //多页面配置插件
const ExtractTextPlugin = require('extract-text-webpack-plugin'); // css 单独打包插件,使用可看官方文档
const CleanWebpackPlugin = require('clean-webpack-plugin');//用于在构建前清除dist目录中的内容
const webpack = require('webpack');//防止重复,抽取公共模块

const srcDir = path.resolve(__dirname, './src');
const distDir = path.resolve(__dirname, './dist');
const plugins = [];
const entrys = getEntry();

//获取多页面的每个入口文件,用于配置中的entry
function getEntry() {

    let files = glob.sync(srcDir+'/js/**/*.js'),
        entry = {},
        entryFileName,
        outputHtmlName;

    for(let i = 0; i < files.length; i++){
        let matchs = /js\/(\S*).js/.exec(files[i]);
        entryFileName = outputHtmlName = matchs[1]; //得到apps/question/index这样的文件名
        if(/^_\w*/.test(entryFileName) || /\/_\w*/.test(entryFileName) || /(com|lib)\//.test(entryFileName))
        {
            continue;
        }

        entryFileName = 'js/'+entryFileName;

        entry[entryFileName] = files[i]
        //生成html配置
        plugins.push(new HtmlWebpackPlugin({
            // 生成出来的html文件名
            filename: distDir+'/html/'+ outputHtmlName + '.html',
            // 每个html的模版,这里多个页面使用同一个模版
            template:srcDir + '/html/'+ outputHtmlName + '.html',
            // 自动将引用插入body
            inject: 'body',
            title:outputHtmlName,
            // 每个html引用的js模块,也可以在这里加上vendor等公用模块
            chunks: [entryFileName,'js/com/common']
        }));
    }

    console.log('> entry' + JSON.stringify(entry))
    return entry;
}

entrys.vendor = ['jquery','d3'];

//抽取css到单独文件
plugins.push(
    new ExtractTextPlugin({
        filename:  (getPath) => {
            return getPath('css/[name].css').replace('css/js', 'css')
        },
        allChunks: true
    })
);

//清除dist构建目录文件
plugins.push(new CleanWebpackPlugin(['dist']));

plugins.push(//公共模块抽取
    new webpack.optimize.CommonsChunkPlugin({
        name: 'js/com/common', // 指定公共 bundle 的名称,表示出了生成后的目录
        minChunks:2, //(模块必须被2个 入口chunk 共享),只要是被两个及以上的chunk引用的公共代码都会被打包到公共模块中
        //chunks: ["js/pages/PageA", "js/pages/PageB"],
        // (只使用这些 入口chunk)
    })
);

module.exports = {
  // JS 执行入口文件
  entry:getEntry(),
  output: {
    //多文件输出
    filename: '[name]_[chunkhash:8].js',// 给输出的文件名称加上 Hash 值
    // 输出文件都放到 dist 目录下
    path: distDir,
  },
  resolve: {  //配置别名,在项目中可缩减引用路径
    alias: {
        jquery: srcDir + "/js/lib/jquery-3.3.1.js",
        d3: srcDir + "/js/lib/d3_3.2.8.js",
    }
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: ['vue-loader'],
      },
      /*{//css打包到js中
        test: /\.scss/,
        use: [{
            loader: 'style-loader'
        }, {
            loader: 'css-loader'
        }, {
            loader: 'sass-loader'
        }]
      }*/
      {//css单独打包
        test: /\.scss/,
        use: ExtractTextPlugin.extract({
            use: [{
                loader:"css-loader"
            },{
                loader: 'sass-loader'
            }],
            fallback: "style-loader"
        })
      }
    ]
  },
  plugins:plugins,
  devtool: 'source-map' // 输出 source-map 方便直接调试 ES6 源码
};

四、更加详细多样的解决方法请参见官网:https://doc.webpack-china.org/plugins/commons-chunk-plugin/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wl_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值