什么是loader
loader是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中
- 处理一个文件可以使用多个loader,loader的执行顺序和配置中的顺序是相反的,即最后一个loader最先执行,第一个loader最后执行
- 第一个执行的loader接收源文件内容作为参数,其它loader接收前一个执行的loader的返回值作为参数,最后执行的loader会返回此模块的JavaScript源码
```bash
// 进入webpack工程中
是你自己的目录地址 npm install /force-strict-loader
// 修改webpack配置 / module: { rules: [ test:/.js$/, use: ‘force-strict-loader’ options: { // 可以自定义参数 } ] } /
```javascript
// mkdir force-strict-loader
// npm init -y
// create index.js
// vi index.js
var loaderUtils = require("loader-utils");
var SourceNode = require("source-map").SourceNode;
var SourceMapConsumer = require("source-map").SourceMapConsumer;
module.exports = function (content, sourceMap) {
if (this.cacheable) {
this.cacheable();
}
var useStrictPrefix = '\'use strict\'; \n\n';
// 获取options的方式
var options = loaderUtils.getOptions(this) || {};
console.log(options);
if (options.sourceMap && sourceMap) {
// 设置sourceMap的方式
console.log("sourceMap");
var currentRequest = loaderUtils.getCurrentRequest(this);
var node = SourceNode.fromStringWithSourceMap(
content,
new SourceMapConsumer(sourceMap)
);
node.prepend(useStrictPrefix);
var result = node.toStringWithSourceMap({
file: currentRequest
});
var callback = this.async();
callback(null, result.code, result.map.toJSON());
}
return useStrictPrefix + content;
}
什么是plugin
在webpack运行的生命周期中会广播出许多事件,plugin可以监听这些事件,在合适的时机通过webpack提供的API改变输出结果。
loader和plugin的区别
对于loader,它是一个转换器,将A文件进行编译形成B文件,这里操作的是文件,比如将A.scss转换为A.css,单纯的文件转换过程
plugin是一个扩展器,它丰富了webpack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,执行广泛的任务
https://webpack.docschina.org/concepts/plugins/
https://v4.webpack.docschina.org/api/compiler-hooks/#root 4 compiler
https://webpack.docschina.org/api/compiler-hooks/#root 5 compiler
https://webpack.docschina.org/api/ compiler 介绍
class MyPlugin{
constructor(options){
console.log("MyPlugin constructor:", options);
}
apply(compiler) {
if (compiler.hooks) {
// 钩子
// https://www.webpackjs.com/api/compiler-hooks/
// 新版本 webpack 5.x
compiler.hooks.compile.tap('MyPlugin', params => {
console.log('以同步方式触及 compile 钩子。一个新的编译(compilation)创建之后')
})
compiler.hooks.done.tap('MyPlugin', params => {
console.log('以同步方式触及 compile 钩子。编译完成时')
})
} else {
// 旧版本
// console.log(compiler);
compiler.plugin("compilation", compilation => {
console.log("MyPlugin");
});
}
}
}
module.exports = MyPlugin;
// webpack.config.js配置:
module.exports = {
//...
plugins: [
new MyPlugin({param: "my plugin"})
]
}
使用该plugin后,执行的顺序:
- webpack启动后,在读取配置的过程中会执行new MyPlugin(options)初始化一个MyPlugin获取其实例
- 在初始化compiler对象后,就会通过compiler.plugin(事件名称,回调函数)监听到webpack广播出来的事件
- 并且可以通过compiler对象去操作webpack
webpack plugins
const ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 自动生成index.html
// 自动清理,清理dist旧文件
// const CleanWebpackPlugin = require('clean-webpack-plugin');
// 升级版本后,自动清理,清理dist旧文件
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {
//...
plugins: [
// 在js中使用_ , 不需要导入
new webpack.ProvidePlugin({
// _: 'lodash'
join: ['lodash', 'join'], // 这种方式会引入 lodash.join方法 而不会加载其他的方法,按需加载效果好
}),
// 替换公共值
new webpack.DefinePlugin({
'process.env.BASE_BUILD': `'${process.env.BASE_BUILD}'`
}),
new ServiceWorkerWebpackPlugin({
// 注意这个项,打包时这个会加上webpack output.path
// 期望生成目录时 /static 目录
filename: '../../../static/hibobi-service-sw.js',
entry: path.resolve(__dirname, './static/service-sw.js')
}),
new CleanWebpackPlugin(), // 自动删除webpack output 对应目录
new HtmlWebpackPlugin({
title: 'VISION-CANVAS-L', // 设置输出文件标题名
filename: 'index.html', // 设置输出文件名
template: 'view/index.html', // 设置模板
})
]
}