持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 12 天,点击查看活动详情
loader
loader是 webpack 当中很重要的一部分,它主要用于对模块代码的转换。loader可以使你在加载import或load的时候预处理文件。因此 loader 相当于其他构建工具当中的task(任务)。
loader可以将模块文件从不同的语言,比如:TypeScript、scss、.vue文件转换成 JavaScript 代码或将内联图像转换为data URL。loader也允许你在 JavaScript 当中直接通过import引入 CSS 文件。
-
安装
loader根据你的项目所需要的loader来安装,比如解析TypeScript就可以安装ts-laoder,npm install ts-laoder --save -dev如果你需要解析其他的模块。可以安装对应的 loader,常用的 loader 有很多,解析 CSS 的 loader:
style-loader css-laoder,解析.vue的 laoder:vue-loader,解析图片的 loader:file-loader等等。 -
使用 loader
laoder的使用有两种方式,一种是在配置文件当中配置,另外一种是在使用import引入的时候进行使用,我们称为配置方式与内联方式。-
配置方式
配置方式是在
webpack.config.js当中对我们所需要使用的laoder进行配置。在module.rules当中,我们可以对模块文件进行文件类型匹配,然后使用对应的loader进行解析。module.exports = { // .... module:{ rules:[ { //匹配对应文件 test:/\.css$/, use:[ //使用style-laoder进行解析 { laoder:'style-loader' }, //使用css-laoder进行解析 { loader:'css-laoder', options:{ modules:true } } ] } ] } }上面我们可以发现,对一个模块文件,我们可以指定多个对应的
laoder进行模块解析。loader 的执行顺序以从右到左或者从下到上解析。上面的 css 文件解析顺序是'css-loader'解析完之后继续执行style-loader。 -
内联方式 内联方式可以在
import或者任何等效与import的方式当中指定模块文件对应的 loader 来解析,比如:import Styles from 'style-loader!css-loader?modules!./styles.css';通过前置的所有规则及使用
!,可以对应覆盖到配置中的任意loader。虽然可以使用这样的方式进行内联配置。但是,webpack 并不推荐我们使用这种方式来进行 loader 配置,因为这样会增加许多的代码,并且对查找错误并不友好。
-
-
loader 解析
loader 的主要功能是将模块文件转成对应的 JavaScript 代码,在 webpack 构建的过程当中,当 webpack 读取到文件之后,会通过对应的 loader 来进行解析,然后将解析完成的模块代码转成
AST抽象语法树。而 loader 的处理流程则是:首先读取模块文件,判断当前文件是否符合某个特定的规则(通过正则匹配),如果符合会读取对应规则当中的 loader 数组,如果不符合,则返回一个空数组,最后对读取的到的数组进行遍历,从右到左或者从下到上依次进行解析,最终输出解析好的模块文件。
Plugins
插件是 webapck 的支柱功能,webpack 自身也是构建于你在 webpack 配置中用到的相同的插件系统之上。插件的目的在于解决loader无法解决的事情。webpack也为我们提供和很多开箱即用的插件。
-
插件是什么? 插件其实是一个 JavaScript 对象,在对象当中定义了一个
apply方法,当webpack compiler调用插件的时候,会调用插件的apply方法,apply方法接收一个compiler参数,当apply方法被调用的时候,会街道到webpack compiler传递进来的一个compiler,它提供了大量的 hook(钩子)函数,plugin 的开发者可以通过注册这些 hooks 函数来参与到 webpack 的编译过程。const pluginName = "ConsoleLogOnBuildWebpackPlugin"; class ConsolePlugin { apply(compiler) { compiler.hooks.run.tap(pluginName, (compilation) => { console.log("webpack 构建正在启动!"); }); } } module.exports = ConsolePlugin;上面的代码我们自定义一个
ConsolePlugin,用于在触发钩子函数的时候打印一些信息。很显然,我们成功了。我们通过compiler对象当中的hooks属性下的run类型,tap事件函数,来实现当中 wenpack 运行的时候打印我们需要的一些信息。compiler.hooks.事件名称.事件类型(name, function (compilation) { //事件处理函数 });我们可以通过上面的方式来注册我们需要的构造函数。其中
name应该是驼峰式命名的插件名称。建议为此使用一个常量,以便它可以在所有 hook 中重复使用。而第二个回调函数,则是当事件触发是需要执行的操作,接收一个compilation参数。我们可以在插件当中传递参数或者选项,以便来更好的扩展插件的功能。
class ConsolePlugin { constructor(options) { this.options = options; } //.... }上面我们通过构造函数来获取到
new实例时接收到的参数,然后再webpack触发回调函数的时候使用,这样就让我们定义的插件扩展性更强,功能也更加强大。 -
plugin 和 loader 的区别 loader 的功能定义是转换模块文件为特定的代码,而一些其他的操作,则无法使用 loader 完成,
- 当 webpack 生成文件时,多生成一个说明文件。
- 当 webpack 编译启动的时候,在控制台输出相关的信息
- 当 webpack 打包完成时,提示结束
- .....
-
总结
我们在使用 webpack 搭建项目的时候,需要使用到非常多的插件月 loader,我们需要理解插件的使用场景以及 loader 的作用范围,这样我们才能在项目构建的时候得心应手。