webpack自定义一个loader
题记
webpack虽然是打包工具之一,但是对于前端rd来说,这是一个跳不过的门槛,最近也是在学习webpack官网,其中对于loader 的描述整体感觉比较简练,想动手试试,感觉还是有点懵懵的,不知道怎么来开始自己的第一个loader,今天我就来分享一下,一个自己手动封装loader的过程,迈出第一步。(ps:后面的步骤会比较详细,有基础的同学多多理解)
一、loader
1.1 为什么要有loader
这也是我们实际项目中会有 .css .less .scss .txt .jpg .vue等等,这些都是webpack无法直接识别打包的文件,都需要使用loader来直接或者间接的进行转换成可以供webpack识别的javascript文件。
1.2 什么是loader
我们知道了为什么要有loader之后,那到底什么是loader?先上一个基本代码:
export default function loader(source) { source = "hello loader!" return `export default ${ JSON.stringify(source) }`; // 返回值 };
这个loader当然在实际工作中不会遇到,也不会用到,只是用来我们学习的,它只干一件事,不管接收到任何数据,都返回“hello loader!”,这个字符串。
二、准备工作
本地安装node环境 mkdir hello-loader && cd hello-loader(创建一个目录,并进来,这就是我们hello-loader的目录了) npm init -y (目的是为了在当前目录初始化,生成一个标准的package.json文件,至于为什么带有-y,大家可以自行搜索哈),截止到目前,当前目录只有一个pakcage.json文件 npm i -D webpack webpack-cli (如果install失败,可能是webpack需要全局安装,改成-g) ,此时当前目录下有node_modules、package.json、package-lock.json,三个文件 依次创建 loader目录,loader/hello-loader.js , main.js, index.html, webpack.config.js (以上所有文件都是空的) 创建一个text.hello 的文件(为什么要建这个奇怪的文件呢,是因为为了体现loader来加载webpack不能识别的文件,你要喜欢爱啥啥,这里我就建了一个.hello格式的文件)
此时项目结构如下:
到此为止,准备工作已经算是完成啦
三、开始动手
3.1 hello-loader.js
就是我们最开始那个代码:
module.exports = function loader(source) { source = "hello loader!" return `export default ${ JSON.stringify(source) }`; // 返回值 };
3.2 main.js
这个在之后的打包中,会是我们的入口文件,因为尽可能简单,这个js中只干一件事,就是加载.hello文件,显示到页面:
// 这里要导入我们创建的文件,因为不是js类型的文件,所以webpack会按照默认的js进行识别打包 // 所以我们这里的导入就是使用文件,来触发loader进行转换 import data from './test.hello'; function test() { let element = document.getElementById('app'); console.log(data); element.innerText = data; } test();
3.3 index.html
从main.js的代码逻辑很简单,就是获取页面中的一个id为app的元素,并将.hello中的值,显示在元素中:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <script src="./output/bundle.js"></script> </div> </body> </html>
这里需要注意几点:
1.我们需要在index中引用./output/bundle.js文件,这是因为这个文件是webpack打包之后的输出文件,
不能引用main.js,至于为什么现在没有,是因为现在还没有执行打包,我先写上去,大家知道就行
2.还有就是这个script标签一定要放在这个div中或者这个标签之后(因为我们刚才main.js中写的是获取id是app的标签,
所以要保证我们的这个div节点已经存在了,我们才能去设置数据,这个是main.js限制的,如果大家没有这么写,可以忽略这个)
3.4 test.hello
里面随便写,如下
随便写没有要求
3.5 webpack.config.js
到此为止,我们的文件基本准本好了,万事具备,就差打包配置了:
const path = require('path'); // node的方法 module.exports = { entry: "./main.js", // 入口文件 mode: "development", output: { // 导入文件配置,也是index.html 引入的 filename: "bundle.js", path: path.resolve(__dirname, "output") }, module: { rules: [ { test: /\.hello$/, // 需要加载的文件类型,正则匹配 loader: [path.resolve(__dirname, './loader/hello-loader.js'),] // 我们的loader文件 } ] } }
到此为止,代码完成
四、验证
4.1 webpack
验证第一步,先打包才能看到,因为loader真正生效的时间节点就是在执行打包:
- webpack根据main.js入口文件,依次加载文件
- 首先发现有一个import .hello 的文件,这个识别不了
- 就是配置中,看有没有对应的loader来解决
- 找到我们的hello-loader
所以,开始动手吧:执行webpack 命令,如果在package.json中配置了build命令可以执行npm run build,没有的话就直接webpack吧
webpack
之后项目目录多了一个文件
4.2 浏览器验证
浏览器打开index.html 文件,可以看到如下
完美说明loader已经生效了!
4.3 反向验证一
在webpack.config.js中注释掉以下代码:
我们来验证是不是如果没有我们的loader,webpack是不是就不能正常加载这个文件,口说无评,注释完,保存,再次执行 webpack,报错如下:
提示无法解析和转化对应的数据,看来没有我们的loader,无法工作,但是它提示的是中文的逗号无法解析,那我们继续验证
4.4 反向验证二
保持上方文件不变哈(就是注视了webpack.config文件的代码)
修改test.hello,改成英文的标点符号:
这里随便写反正也读不出来
再执行webpack,这次没有报错,看起来还不错,刷新浏览器,一片空白(就不截图了),控制台报错了:
说明文件并没有正确的解析,只是按照默认的js格式进行解析了
4.5 最后一步
首先恢复webpack.config.js,启用我们的loader:
然后更新一下hello-loader.js:
只是注释掉一行代码
打包
刷新浏览器:
到此为止,入门完成
代码上传到git,大家可以拉去到本地,执行npm i即可