js-工程化webpack loader和plugin

413 阅读4分钟

常用loader

  • raw-loader:加载文件原始内容(utf-8)\
  • file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件 (处理图片和字体)\
  • url-loader:与 file-loader 类似,区别是用户可以设置一个阈值,大于阈值会交给 file-loader 处理,小于阈值时返回文件 base64 形式编码 (处理图片和字体)\
  • source-map-loader:加载额外的 Source Map 文件,以方便断点调试\
  • svg-inline-loader:将压缩后的 SVG 内容注入代码中\
  • image-loader:加载并且压缩图片文件\
  • json-loader 加载 JSON 文件(默认包含)\
  • handlebars-loader: 将 Handlebars 模版编译成函数并返回\
  • babel-loader:把 ES6 转换成 ES5\
  • ts-loader: 将 TypeScript 转换成 JavaScript\
  • awesome-typescript-loader:将 TypeScript 转换成 JavaScript,性能优于 ts-loader\
  • sass-loader:将SCSS/SASS代码转换成CSS\
  • css-loader:加载 CSS,支持模块化、压缩、文件导入等特性\
  • style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS\
  • postcss-loader:扩展 CSS 语法,使用下一代 CSS,可以配合 autoprefixer 插件自动补齐 CSS3 前缀
  • eslint-loader:通过 ESLint 检查 JavaScript 代码\
  • tslint-loader:通过 TSLint检查 TypeScript 代码\
  • mocha-loader:加载 Mocha 测试用例的代码\
  • coverjs-loader:计算测试的覆盖率\
  • vue-loader:加载 Vue.js 单文件组件\
  • i18n-loader: 国际化\
  • cache-loader: 可以在一些性能开销较大的 Loader 之前添加,目的是将结果缓存到磁盘里

-- 如何编写loader

  • Loader 支持链式调用,所以开发上需要严格遵循“单一职责”,每个 Loader 只负责自己需要负责的事情。\
  • Loader的API 可以去官网查阅
  • Loader 运行在 Node.js 中,我们可以调用任意 Node.js 自带的 API 或者安装第三方模块进行调用Webpack 传给 Loader 的原内容都是 UTF-8 格式编码的字符串,当某些场景下 Loader 处理二进制文件时,需要通过 exports.raw = true 告诉 Webpack 该 Loader 是否需要二进制数据尽可能的异步化 Loader,如果计算量很小,同步也可以Loader 是无状态的,我们不应该在 Loader 中保留状态使用 loader-utils 和 schema-utils 为我们提供的实用工具加载本地 Loader 方法 Npm linkResolveLoader

常用plugin

  • define-plugin:定义环境变量 (Webpack4 之后指定 mode 会自动配置)\
  • ignore-plugin:忽略部分文件\
  • html-webpack-plugin:简化 HTML 文件创建 (依赖于 html-loader)\
  • web-webpack-plugin:可方便地为单页应用输出 HTML,比 html-webpack-plugin 好用\
  • uglifyjs-webpack-plugin:不支持 ES6 压缩 (Webpack4 以前)\
  • terser-webpack-plugin: 支持压缩 ES6 (Webpack4)\
  • webpack-parallel-uglify-plugin: 多进程执行代码压缩,提升构建速度\
  • mini-css-extract-plugin: 分离样式文件,CSS 提取为独立文件,支持按需加载 (替代extract-text-webpack-plugin)\
  • serviceworker-webpack-plugin:为网页应用增加离线缓存功能\
  • clean-webpack-plugin: 目录清理\
  • ModuleConcatenationPlugin: 开启 Scope Hoisting\
  • speed-measure-webpack-plugin: 可以看到每个 Loader 和 Plugin 执行耗时 (整个打包耗时、每个 Plugin 和 Loader 耗时)\
  • webpack-bundle-analyzer: 可视化 Webpack 输出文件的体积 (业务组件、依赖第三方模块)

--如何编写plugin

  • webpack 的 Plugin 是一个导出的类,类中含有 apply 方法,能够在编译周期内访问到 compiler 对象,可以在 apply 方法中调用 compiler hooks,定义在编译的某个时期执行该 Plugin 进行某些操作

    class ConsoleLogOnBuildWebpackPlugin {
        apply(compiler) {
            compiler.hooks.run.tap(pluginName, compilation => {
                console.log("webpack 构建过程开始!");
            });
        }
    }
    
    • webpack在运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在特定的阶段钩入想要添加的自定义功能。Webpack 的 Tapable 事件流机制保证了插件的有序性,使得整个系统扩展性良好。\Plugin的API 可以去官网查阅
    • compiler 暴露了和 Webpack 整个生命周期相关的钩子compilation 暴露了与模块和依赖有关的粒度更小的事件钩子插件需要在其原型上绑定apply方法,才能访问 compiler 实例传给每个插件的 compiler 和 compilation对象都是同一个引用,若在一个插件中修改了它们身上的属性,会影响后面的插件找出合适的事件点去完成想要的功能
    • emit 事件发生时,可以读取到最终输出的资源、代码块、模块及其依赖,并进行修改(emit 事件是修改 Webpack 输出资源的最后时机)watch-run 当依赖的文件发生变化时会触发\异步的事件需要在插件处理完任务时调用回调函数通知 Webpack 进入下一个流程,不然会卡住

实战中:提高效率的插件

  • webpack-dashboard:可以更友好的展示相关打包信息。\
  • webpack-merge:提取公共配置,减少重复配置代码\
  • speed-measure-webpack-plugin:简称 SMP,分析出 Webpack 打包过程中 Loader 和 Plugin 的耗时,有助于找到构建过程中的性能瓶颈。\
  • size-plugin:监控资源体积变化,尽早发现问题\
  • HotModuleReplacementPlugin:模块热替换