持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
回顾
loader可以把webpack除过js、json外不能解析的文件转换成webpack可以解析的文件,是一个解析器,翻译官。
一个loader只能干一件事情,并且是有顺序的。
使用loader
例如:webpack项目里要使用一个less文件,但是Webpack不支持,所以,需要使用loader。
首先安装:
npm install style-less css-loader less less-loader
因为less-loader依赖于less所以也需要安装less,less-loader是把less转换成css,而css-loader是把css进行了序列化,处理添加到出口文件中,style-loader是把通过在html头部head里动态创建style 标签,把样式添加在里面,把序列化的css转换成样式。
然后在webpack.config.js里面进行配置loader,样式就可以成功显示了。
webpack.config.js:
const path = require("path");
module.exports = {
// entry:'./src/other.js',
entry: {
index: './src/index.js',
list: './src/list.js'
},
output: {
filename: "[name].js",//利用占位符,文件名不要重复
path: path.resolve(__dirname, "dist")//输出⽂件到磁盘的⽬录,必须是绝对路径
},
mode: 'development',
module: {
rules: [
{
test: /.css$/,
use: ["style-loader","css-loader"]
},
{
test: /.less$/,
use: ["style-loader","css-loader","less-loader"]
},
]
}
}
注意配置里面的顺序,是自右向左的。
项目目录:
可以看一下重要的文件代码:
src/index.js :
import {add} from './other.js'
import css from "./index.css";
import test from "./test.less";
const json =require('./index.json')
console.log(json,add(1,2));
console.log('哈哈');
src/index.css:
body{
background: red;
}
src/test.less:
body{
div{
background: blue;
}
}
dist/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="index.js"></script>
</head>
<body>
<div>这是个webpack项目</div>
</body>
</html>
配置文件webpack.config.js上面已经展示。 打开dist/index.html页面看下效果。

手写实现loader
现在我们实现上面三个loader,style-loader,css-loader,less-loader。
手写less-loader
先实现less-loader:
myLoaders/test-less-loader:
const less = require('less');
module.exports = function (sourse) {
less.render(sourse, (e, output) => {
this.callback(e, output.css)
})
}
这里工作机制是,项目运行时,看到less文件,然后就直接走到test-less-loader这个js文件里。然后这个js文件里面接受的参数就是less文件的内容。
这里其实就是把less转换成css返回了。
首先引入我们安装好的less,然后写一个导出的函数,这个函数接受的参数就是我们less文件里面的内容,然后用less自带的render编译器,进行传参数,第一个参数是要转化的less内容,第二个参数是一个函数,函数里的output.css就是转换后的css内容。
然后我们用this.callback把转换后的css返回。
想更加深入的了解less.render的或者less其他内容时,可去less官网 截取几个官网less.render的例子代码:

手写css-loader
再来实现css-loader:
myLoaders/test-css-loader:
module.exports=function(sourse){
console.log(sourse);
return JSON.stringify(sourse);
}
这个也比较简单,代码很短,这里做的处理就只是把css代码序列化,用JSON.stringify就ok了,然后再导出的函数里面返回,因为css-loader本来做的事情就只有意见,把css代码序列化。
手写style-loader
最后再来实现style-loader:
style-loader做了一件事就是在html的头部head里动态创建style标签,然后把css样式放进去。
myLoaders/test-style-loader:
module.exports = function (sourse) {
return `const ele=document.createElement('style');
ele.innerHTML=${sourse};
document.head.appendChild(ele);`
}
这段代码就是做了上面说的事情。
最后别忘了要修改配置,之前引用的是人家官方的loader,现在都改成我们自己写的loader。
加了一行指向loader的本地文件夹:

分别指向的是,原本的node_modules,和我们创建的myLoaders模块。默认的是只指向node_modules模块。
这块也做修改,改成我们自己写的loader:

配置文件全部代码:
webpack.config.js:
const path = require("path");
module.exports = {
// entry:'./src/other.js',
entry: {
index: './src/index.js',
list: './src/list.js'
},
output: {
filename: "[name].js",//利用占位符,文件名不要重复
path: path.resolve(__dirname, "dist")//输出⽂件到磁盘的⽬录,必须是绝对路径
},
mode: 'development',
resolveLoader:{
modules:['node_modules','myLoaders']
},
module: {
rules: [
{
test: /.css$/,
use: ["style-loader","css-loader"]
},
{
test: /.less$/,
use: ["test-style-loader","test-css-loader","test-less-loader"]
},
{
test: /.sass$/,
use: ["style-loader","css-loader","sass-loader"]
},
]
}
}
最后执行构建npm run...,重新打包,看下效果:
构建成功后,看下dist/index.js出口文件:

可以看到我们刚才自己的loader的代码,再看下dist/index.html的页面效果:

跟官方的loader效果一模一样,成功啦。
完结
以上我们就把手写style-loader,css-loader,less-loader,写完了,代码很短,也挺简单的,其实只要知道每个loader都干了一件什么事情,我们去实现这个是事情就好啦。