一、webpack配置问题
- 常用的loader有哪些?
样式:style-loader、css-loader、less-loader、postcss-loader; 图片等:url-loader、file-loader; es6:babel-loader。 - 常用的plugin有哪些?
clean-webpack-plugin、html-webpack-plugin、mini-css-extract-plugin; webpack自带的插件:HotModuleReplacementPlugin、providePlugin(shimming) - loader和plugin有什么区别?
loader是当我们进行打包我们的文件时,处理不同类型的文件,处理模块。plugiin是在打包的时候具体时刻,进行处理事件。 - webpack如何抽离压缩css文件?
利用mini-css-extract-plugin插件抽离css文件,optimize-css-assets-webpack-plugin用于压缩css文件。
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
...
module:{
rules:[
{
test:/\.css$/,
use:[
MiniCssExtractPlugin.loader,
{
loader:"css-loader",
options:{
importLoaders:1
}
},
"postcss-loader"
],
},
...
plugins: [new MiniCssExtractPlugin({
filename:'css/main.[contenthash].css'
})]
optimization: {
minimizer: [new OptimizeCssAssetsPlugin({})]
}
- webpack怎样抽离公共代码和第三方库?
利用splitChunkPlugin可以实现代码分割,在缓存组配置分割第三方库和公共代码。
optimization: {
splitChunks:{
cacheGroups: {
// 如果引入的包是node_modules里面的内容,会进入到这里的配置
vendors: {
test: /[\\/]node_modules[\\/]/,//检测引入的第三方库是不是node_modules里面的内容
priority: -10,
filename: 'vendors.js'
},
// 如果引入的包不是node_modules里面的内容,会进入到这里的配置
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
filename: 'common.js'
}
}
}
}
- webpack如何实现异步加载js?
利用import引入,/* webpackChunkName:"lodash"*/设置打包输出的文件名。
function getComponent () {
return import(/* webpackChunkName:"lodash"*/'lodash').then(({default: _}) => {
var element = document.createElement('div')
element.innerHTML = _.join(['a','b','c'],'***')
return element
})
}
// 点击页面才会执行
document.addEventListener('click', () => {
getComponent ().then((element) => {
document.body.appendChild(element)
})
})
- @babel/polyfill如何按需引入?
默认的Babel只⽀持let等⼀些基础的特性转换, Promise等⼀些还有转换过来,这时候需要借助@babel/polyfill,以查找目标环境中缺少的功能,并且仅包括所需的polyfill。
#业务代码打包场景
//新建.babelrc文件
{"presets": [
[
"@babel/env",
{
//兼容的浏览器设置
"targets": "> 0.2%, not dead",
//按需注入,使用了usage,会自动引入import "@babel/polyfill",
//无需在js中引入
"useBuiltIns": "usage",
}
]
]
}
- module、chunk和bundle的区别?
module指各个源码文件,webpack一切皆模块;而chunk指entry入口文件、import懒加载、splitChunk多模块合成的;bundle指最终输出的文件。 - 如何配置多页面打包?
打包之后有两个html页面,一个引入index.js打包之后的文件,一个引入list.js打包之后的文件。那么需要配置两个entry,遍历entry设置chunks。
// 入口文件
entry: {
main: './src/index.js',
list: './src/list.js'
},
const path = require('path')
// 将我们写的html文件,进行打包;
const HtmlWebpakcPlugin = require('html-webpack-plugin')
const makePlugins = (configs) => {
const plugins = [new CleanWebpackPlugin()]
const files = fs.readdirSync(path.resolve(__dirname, './dll'))
Object.keys(configs.entry).forEach(item => [
plugins.push(new HtmlWebpakcPlugin({
template: './src/index.html',
filename: `${item}.html`,
chunks: ['runtime', 'vendors', item]
}))
]);
return plugins;
}
const configs = {
// 配置打包模式
mode: 'development',
devtool: 'cheap-module-eval-source-map',
// 入口文件
entry: {
main: './src/index.js',
list: './src/list.js'
},
...
}
module.exports = configs
configs.plugins = makePlugins(configs)
二、webpack性能优化
- 怎样优化打包构建速度?
- 优化babel-loader,明确范围,可以通过includes以及excludes等选项,进行配置不对其他库文件进行转换。
- tread-loader, parallel-webpack, happypack 多进程打包,webpack-parallel-uglify-plugin多进程压缩。 需要注意的是:项目较大时,开启多进程打包可以提高速度;但项目较小时,由于进程开销,可能会降低速度。
- 开发环境:开启自动刷新和热更新。
利用webpack.HotModuleReplacementPlugin插件
if (module.hot) { module.hot.accept('./number.js', function() { number(); }) }-
开发环境:使用DllPlugin提高打包速度。前端框架体积较大,构建慢,较稳定,不常更新版本,同一个版本只需构建一次。
-
对于产出代码可以考虑三个方面:体积更小、合理分包不重复加载、速度更快内存使用更小。 小图片可以使用url-loader转换为base64编码、懒加载、bundle加contenthash缓存、利用splitChunkPlugin提取公共代码、通过Tree Shaking进行去除没有使用的包。