共计 2078 个字符,预计需要花费 6 分钟才能阅读完成。
webpack loader 学习
初识 loader
webpack 入门基本都看过它,webpack 最主要的功能就是把蓝色菱形左边各式各样的模块全部打包成右边这几种统一规范的文件,而核心蓝色菱形就是 loader。
举几个小例子:
- vue 文件 需要用到 vue-loader
- es6 语法 需要使用 babel-loder
- sass 样式文件 需要用到 sass-loader
- …
loader 是什么
- 本质上来说 loader 是一个 node 模块
- 是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中
- loader 支持链式调用,依次调用,同一种文件支持多个 loader 自下而上执行
loader 基本使用
这是一个 webpack.base.confi.js 的 module 配置,一些文件所需要的 loader 一般写在 module.rules 中。test 定义的是正则匹配文件类型,loader 是定义编译此文件所需要的 loader 工具名 ,options、include 都是一些相关配置文件,这里不做赘述。
实现一个非常简单的 loader
从零开始新建一个文件夹 loader-study
npm init
webpack init
npm install
来创建一个简单的打包工具。
在 webpack init 过程中遇到加入 css babel 这样的 loader 的时候都可以选择否,我们实现的重点不在这块。
下面贴一下 webpack.config.js 的代码,都是些 webpack 基本配置,重点是 module.rules 里面的 loader 配置,我们这次要实现的是一个解析 txt 文件的 loader,命名为 self-loader.
const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin')
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
entry: {app: './app.js'},
output: {
filename: 'result.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{ // 这个 loader 是我们自己实现的 loader
test: /\.txt$/,
loader: 'self-loader'
}
]
},
plugins: [new UglifyJSPlugin(), new HtmlWebpackPlugin({
template: './index.html',
filename: './output.html'
})]
};
接下来你需要在 node_modules 文件夹中创建一个 self-loader 文件夹并在此文件夹下创建一个 index.js。先上代码等下解释。
module.exports = function(source) {var str = source.split('').join('-')
return `module.exports = '${str}'`
}
在 webpack 中配置好了 loader 匹配规则,遇到 txt 文件都会进入这个 loader 方法,此方法的 source 参数会拿到 txt 文件中的所有内容,然后我们可以对这些内容进行处理之后返回。
为什么不直接返回,而是 return module.exports = ${source}
我想各位都知道,拿到返回内容使用得 import,这里必须 export。
然后我们再创建一个 app.js 文件, 用来展示我们的 loader 成果
import hhh from'./test.txt'
document.body.innerText = hhh
console.log(hhh)
结果展示
test.txt 内容:我是一个 txt 内容
页面输出:
我 - 是 - 一 - 个 -t-x-t- 内 - 容
package.json 配置
"dev": "webpack-dev-server --inline --progress --config webpack.config.js",
"build": "webpack"
npm run build 可以在 dist 文件中看到打包出来的 index.html 文件中,loader 对 txt 文件的处理效果。
部分疑问
- 本文实现的 loader 作用仅仅局限于 txt 文件,那 babel-loader、css-loader 这些大概是怎么实现的?
答:简单来讲,比如 babel-loader, 他在拿到 js 文件后会把 js 代码 转换成一个抽象语法树,类似于 json 的一个结构,然后通过特定的编译规则把 es6 的一些语法替换成 es5 的语法来达到编译的效果。
- loader 中是否有更多的操作方法?
答:是的 loader 中的 source 只是第一个参数,可以同在 this.query 获取在 module.rules 中配置的 options 参数。还有就是多个 loader 同步执行的时候使用 this.callback(null,source,map,meta), 可以更灵活的操作 source。