首先创建一个文件夹,并执行npm init -y
mkdir my-loader
cd my-loader
npm init -y
复制代码
这样就生成了package.json
{
"name": "my-loader",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
复制代码
然后安装webpack webpack-cli
npm install webpack webpack-cli --save-dev
复制代码
接下来创建src目录,并创建index.js文件
// src/index.js
console.log('Hello Huan');
复制代码
再创建配置文件
// webpack.config.js
const path = require('path');
module.exports = {
entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
}
}
复制代码
修改package.json
"scripts": {
"build": "webpack"
},
复制代码
然后执行
npm run build
复制代码
此时在控制台会看到如下提示
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
复制代码
我们需要在webpack.config.js中加上mode配置
// webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',
entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
}
}
复制代码
然后再执行
npm run build
复制代码
在dist目录中生成了main.js,在文件末尾便能看到打包后的业务代码
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/*! no static exports found */
/***/ (function(module, exports) {
eval("console.log('Hello webpack');\n\n//# sourceURL=webpack:///./src/index.js?");
/***/ })
/******/ });
复制代码
现在我们想在加载index.js时,将Huan替换为HuanLiu,这时就需要写一个loader来做这个事情
创建如下文件
// loaders/replaceLoader.js
module.exports = function (resource) {
return resource.replace('Huan', 'HuanLiu');
}
复制代码
注意上面的函数不能写成箭头函数,否则,在函数内部使用的this将不能调用到webpack的方法与属性。
然后在webpack.config.js中添加如下内容
// webpack.config.js
module.exports = {
...
module: {
rules: [
{
test: /\.js/,
use: [
path.resolve(__dirname, './loaders/replaceLoader.js')
]
}
]
}
}
复制代码
然后执行打包
npm run build
复制代码
再打开main.js,能看到Huan已经替换成了HuanLiu
eval("console.log('Hello HuanLiu');\n\n//# sourceURL=webpack:///./src/index.js?");
复制代码
这样我们就实现了一个最简单的loader。
现在我们再做稍微复杂一点的配置
// webpack.config.js
module: {
rules: [
{
test: /\.js/,
use: [
{
loader: path.resolve(__dirname, './loaders/replaceLoader.js'),
options: {
name: 'liu'
}
}
]
}
]
}
复制代码
修改replaceLoader.js
// loaders/replaceLoader.js
module.exports = function (resource) {
return resource.replace('Huan', this.query.name);
}
复制代码
上述代码通过this.query
就能获取到options
中的属性
再执行打包npm run build
,就能看到打包后的代码如下所示
eval("console.log('Hello liu');\n\n//# sourceURL=webpack:///./src/index.js?");
复制代码
我们还可以通过官方推荐的loader-utils来获取webpack.config.js中配置的options属性 首先安装loader-utils
npm install loader-utils --save-dev
复制代码
然后修改replaceLoader.js
const loadUtils = require('loader-utils');
module.exports = function (resource) {
const options = loadUtils.getOptions(this);
return resource.replace('Huan', options.name);
}
复制代码
再执行打包npm run build
,打包后的结果与前面一样
eval("console.log('Hello liu');\n\n//# sourceURL=webpack:///./src/index.js?");
复制代码
loader还有很多Api可供我们使用
this.callback(
err: Error | null,
content: string | Buffer,
sourceMap?: SourceMap,
meta?: any
);
复制代码
使用callback我们能传递更多信息给replaceLoader,我们这里只使用了前两个参数
const loadUtils = require('loader-utils');
module.exports = function (resource) {
const options = loadUtils.getOptions(this);
const result = resource.replace('Huan', options.name);
this.callback(null, result);
}
复制代码
再执行打包npm run build
,所得结果跟之前一样。
至此,我们就编写了一个简单的loader,并讲解了其中的一些配置。
在下一节我们将继续学习如何编写一个Loader的更深入些的内容。