20下半年面试题-webpack - 愚墨的博客
1、webpack loader和plugin的区别
loader 赋予了webpack处理其他类型文件的能力,比如css、图片等。
plugin是用来增强文webpack的打包能力,让webpack有更多的活性。
2、如何编写一个plugin
常用plugin
terser-webpack-plugin 代码优化压缩工具
webpack-bundle-analyzer bundle分析工具
html-webpack-plugin html模板生成插件
类的编写方式
class CreateVersionsMapping {
constructor(options) {
this.options = options;
}
apply(compiler) {
// const outputName = this.options.outputName || 'versions.mapping';
compiler.hooks.emit.tap('createVm', (compilation) => {
// callback();
});
}
}
module.exports = CreateVersionsMapping;
方法实现
function HelloWorldPlugin(options) {
// 使用 options 设置插件实例……
}
HelloWorldPlugin.prototype.apply = function(compiler) {
compiler.plugin('done', function() {
console.log('Hello World!');
});
};
module.exports = HelloWorldPlugin;
//webpack 5
const taskPlugin=function (){
}
taskPlugin.prototype.apply = function(compiler) {
let start;
let end;
compiler.hooks.initialize.tap('taskPlugin', (context, entry) => {
console.log('编译器初始化!!!!!');
start=new Date().getTime()
});
compiler.hooks.beforeRun.tap('taskPlugin', (context, entry) => {
console.log('编译前!!!!!');
});
compiler.hooks.emit.tap('taskPlugin', (context, entry) => {
console.log('输出前!!!!!');
});
compiler.hooks.afterEmit.tap('taskPlugin', (context, entry) => {
console.log('输出之后!!!!!');
});
compiler.hooks.done.tap('taskPlugin', (context, entry) => {
end=new Date().getTime()
console.log('编译耗时='+(end-start));
});
};
module.exports = taskPlugin;
3、如何使用webpack项目优化
1、JS相关优化
optimization.minimizer 里面,配置TerserPlugin插件,压缩代码
optimization.splitChunks
,分割代码,抽取公共代码
tree shaking 去除多余无用代码 (在 package.json中配置"sideEffects": false 或者一个数组)
config.optimization.minimizer = [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: false,
},
},
}),
]
2、CSS优化
postcss自动加样式前缀
// 提取css到单独的文件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// optimizeCssPlugin CSS文件压缩插件
const optimizeCssPlugin = require('optimize-css-assets-webpack-plugin');
4、loader
module.exports = function(content, map, meta) {
return someSyncOperation(content);
};
module.exports = function(content, map, meta) {
this.callback(null, someSyncOperation(content), map, meta);
return; // 当调用 callback() 时总是返回 undefined
};
异步 loader
对于异步 loader,使用 this.async 来获取 callback 函数
module.exports = function(content, map, meta) {
var callback = this.async();
someAsyncOperation(content, function(err, result) {
if (err) return callback(err);
callback(null, result, map, meta);
});
};
所谓 loader 只是一个导出为函数的 JavaScript 模块。loader runner 会调用这个函数,然后把上一个 loader 产生的结果或者资源文件(resource file)传入进去。
如果是单个处理结果,可以在同步模式中直接return返回。如果有多个处理结果,则必须调用 this.callback()
在异步模式中,必须调用 this.async(),来指示 loader runner 等待异步结果,它会返回 this.callback() 回调函数,随后 loader 必须返回 undefined 并且调用该回调函数。