摘要:多页⾯中公⽤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 = solve(__dirname, './src');
const distDir = solve(__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)
})
);
// JS 执⾏⼊⼝⽂件
entry:getEntry(),
output: {
//多⽂件输出
filename: '[name]_[chunkhash:8].js',// 给输出的⽂件名称加上 Hash 值
// 输出⽂件都放到 dist ⽬录下
path: distDir,
},
resolve: { //配置别名,在项⽬中可缩减引⽤路径
alias: {
jquery: srcDir + "/js/lib/jquery-3.3.1.js",
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: act({
use: [{
loader:"css-loader"
},{
loader: 'sass-loader'
}],
fallback: "style-loader"
})
}
]
},
plugins:plugins,
devtool: 'source-map'// 输出 source-map ⽅便直接调试 ES6 源码};
发布评论