手机版

网络包加载器和插件编写的详细说明

时间:2021-08-29 来源:互联网 编辑:宝哥软件园 浏览:

1基础复习

首先,让我们回顾一下webpack的常见配置,因为它将在以后使用,所以我们将简要介绍它。

1.1 web包的常见配置

//条目文件条目: { app 3360 }。/src/js/index.js ',},//输出文件output3360 {filename3360' [name]。bundle.js ',path 3360 path . resolve(_ dirname,Dist '),publicPath: '/' //确保可以在http://localhost:3000}下正确访问文件资源,//开发人员工具source-map dev工具:' inline-source-map ',//创建开发人员服务器devserver3360 {contentbase: '。/dist ',hot: true//hot update},plugin3360 [//delete dist目录new cleanwebpackkplugin([' dist ']),//重新穿戴html文件new htmlwebpackkplugin({ title : ' output management ' }),//这样更容易查看待修补的依赖项newwebpack.namemodulesplash()。//hot update module new web pack . hot module ereplacement plugin()],//environment mode : ' development ',//loader配置module : { rules 3360 [{ test 3360/\。CSS $/,Use: ['style-loader ',' CSS-loader']},{test3360/\。(png | SVG | jpg | gif) $/,use3360 ['file-loader']}]}这里我们重点关注模块和插件属性,因为今天的重点是编写loader和

1.2包装原则

识别输入文件取决于逐层识别模块。(Commonjs、amd或es6的导入将由webpack进行分析。获取代码依赖项。)webpack所做的就是分析代码。转换代码、编译代码、输出代码、最后形成打包代码是webpack的一些基础知识,对理解webpack的工作机制很有帮助。

2装载机

好了,今天第一个主角就要出现了

2.1什么是装载机?

Loader是一个文件加载器,可以加载资源文件,对这些文件进行一些处理,比如编译、压缩等。最后将它们打包到指定的文件中

一个文件可以使用多个加载器进行处理,加载器执行的顺序与其自身顺序相反,即最后一个加载器先执行,第一个加载器后执行。第一次执行的加载器接收源文件的内容作为参数,其他加载器接收前一次执行的加载器的返回值作为参数。最后执行的加载器将返回这个模块的JavaScript源代码2.2,并手工编写一个加载器

要求:

把手。并反转字符串。首字母大写。例如,abcdefg转换为Gfedcba

好,我们开始吧

1)首先,创建两个加载器(这里,以本地加载器为例)

为什么要创造两个劳德?原因将在后面介绍

反向加载器. js

module . exports=function(src){ if(src){ console . log('-reverse-loader input : ',src) src=src.split(')。反转()。join(“”)console . log(“-reverse-loader output :”,src) }返回src;}大写-loader.js

module . exports=function(Src){ if(Src){ console . log('-大写-loader input: ',Src) src=src.charat (0)。touppercase(). src . slice(1)console . log('-大写-loader output : ',src)}//为什么在这里写这个?因为直接返回转换后的字符串会报告语法错误,//写入import并将其转换为可用的字符串return ` module。exports=' $ {src}' `}。看看装载机结构是不是很简单。接收参数并返回内容是可以的。

然后创建一个txt文件

2)mytest.txt

Abcdefg3)立即开始配置webpack

module . exports={ entry : { index : }。/src/js/index.js' },plugins: [.],optimization: {.},output: {.},Module : { rule 3360[.{test:/\。txt $/,use: ['。/loader/大写-loader.js ','。/loader/reverse-loader . js ']]]} }这样配置就完成了

4)我们将该脚本导入门户文件

为什么我们需要在这里进口?我们不是配置了webapck来处理所有。txt文件?

因为webpack将进行过滤,所以如果文件没有被引用,webpack将不会打包该文件,并且您的加载程序也不会执行它。

import _ from ' lodash从导入txt./txt/mytest.txt'import './CSS/style . CSS ' function component(){ var element=document . create element(' div ');var button=document . createelement(' button ');var br=document . create element(' br ');button.innerHTML=“点击我,看看控制台!”;element.innerHTML=_。join('【' txt ' 】');element . class name=' hello ' element . appendchild(br);element.appendChild(按钮);//请注意,因为涉及到网络请求,所以需要在生产级站点/应用程序中显示一些加载指示//。button . onclick=e=import(/* WebPACKchunk name : ' print ' */'。/print ')。然后(module={ var print=module . default;print();});返回元素;} document . body . appendchild(component());Package.json配置

{ .' scripts ' : { ' test ' : ' echo ' error :未指定测试' exit 1 ',' build ' : ' web pack-config web pack . prod . js ',Start ' : ' web pack-dev-server-open-config web pack . dev . js ',' server' :' nodeserver.js'},}然后执行命令

npm运行构建

然后我们的装载机就完成了。

为什么要写两个加载器?

看到执行的顺序,我们的配置是这样的

使用: ['。/loader/大写-loader.js ','。/loader/reverse-loader.js']如上所述,一个文件可以使用多个加载器进行处理,加载器执行的顺序与加载器本身的顺序相反

我们还可以编写自己的加载器来解析定制模板。例如,vue-loader非常复杂,它会编写大量的解析。vue文件,然后生成相应的html、js和css。

我们这里只谈一个基本用法。如果有更多需要,可以查看《loader官方文档》。

3插件

3.1什么是插件?

Webpack的生命周期中会广播很多事件,Plugin可以监听这些事件,在合适的时候通过Webpack提供的API改变输出结果。

插件和加载器有什么区别?

对于loader来说,它是一个转换器,把A文件编译成B文件,在这里操作文件,比如把A . SCS或者A.less转换成B.css,一个简单的文件转换过程

Plugin是一个扩展程序,它丰富了wepack本身。它针对的是装载机完成后WEPACK包装的全过程。它不直接操作文件,而是基于事件机制工作,会监听WEPACK打包过程中的一些节点,执行广泛的任务。

3.2最简单的插件

/plugins/MyPlugin.js(本地插件)

类MyPlugin {//构造函数(选项){ console . log(' my plugin constructor 3360 ',选项)} //应用函数apply(编译器){//绑定钩子事件编译器. plugin(' compile ',compile={ console . log(' my plugin ')))} }模块. exports=myplugin web pack配置

const MyPlugin=require('。/plugins/MyPlugin ')模块。exports={ entry : { index : }。/src/js/index.js' },plugins: [.新的MyPlugin({param: 'xxx'}) ],};这是最简单的插件(虽然我们什么都没做)

webpack启动后,在读取配置的过程中,会执行新的MyPlugin(选项)来初始化一个MyPlugin来获取它的实例。初始化编译器对象后,调用myPlugin.apply(编译器)将编译器对象传入插件实例。得到编译器对象后,插件实例可以通过compiler.plugin(事件名称,回调函数)监听Webpack广播的事件。并且可以通过编译器对象来操作webpack。看到这里,你可能会问什么是编译器,什么是编译。

编译器对象包含Webpack环境的所有配置信息,包括选项、加载器和插件。启动Webpack时,该对象被实例化。它是全球唯一的,可以简单地理解为一个Webpack实例。

编译对象包含当前模块资源、编译资源、更改的文件等。当Webpack在开发模式下运行时,每次检测到文件更改,都会创建一个新的编译。编译对象还为插件扩展提供了许多事件回调。编译器对象也可以通过编译来读取。

编译器和编译的不同之处在于:

编译器代表整个Webpack从启动到关闭的生命周期,而编译只代表一次新的编译。

3.3事件流程

Webpack通过Tapable组织了这条复杂的生产线。webpack的事件流机制保证了插件的顺序,使得整个系统具有可扩展性。webpack的事件流机制应用了观察者模式,这与Node.js中的EventEmitter非常相似.绑定事件

compiler.plugin('event-name ',params={.});触发事件

编译器。应用('事件名称',参数)3.4注意事项

只要能得到Compiler或者Compiler对象,就可以广播新的事件,所以新开发的插件也可以广播事件给其他插件听。传递给每个插件的编译器和编译对象是相同的引用。也就是说,在一个插件中修改编译器或编译对象的属性会影响其背后的插件。有些事件是异步的,这些异步事件将伴随着两个参数。第二个参数是回调函数。当插件完成处理任务后,需要调用回调函数通知webpack,然后才能进入下一个处理流程。例如:编译器。插件(' emit ',函数(编译,回调){ 0.//处理后执行回调通知Webpack //如果不执行回调,运行的进程会一直卡在这里。});关于编译器和编译,webpack定义了大量的钩子事件。开发人员可以根据自己的需要在任何地方定制处理。

《compiler钩子文档》

《compilation钩子文档》

3.5手工编写插件

场景:

小程序的mpvue项目由webpack编译,生成子包(我们作为子包引入到主程序中),然后被接纳到主包中。生成子包后,子包中公共静态资源wxss的引用地址需要添加分包前缀:/subpage/enjoy _ given。

在编写插件之前,生成的资源是这样的。如果该路径作为分包合同被引入到主包中,资源将无法正常访问。

需求是这样的:

修改所有页面的样式文件(wxss文件)引入dist/static/css/pages目录下的公共资源的路径。

因为所有页面的样式都参考了一般的样式供应商. wxss

然后需要放@ import/static/CSS/vendor . wxss ';更改为:@ import '/子页/enjoy _ given/static/CSS/vendor . wxss ';复制代码

好,走吧!

1)创建插件文件CssPathTransfor.js

CSS path transfer . js

类CssPathTransfor { apply(编译器){ compiler.plugin('emit ',(编译,回调)={ console . log('-cssspathttransfer emit ')//遍历(var文件路径名在编译中)的所有资源文件。assets){//如果(/static \/CSS \/pages/I . test(file pathname)){//引入正则construg=/\/static \/CSS \/vendor \,则检查对应的文件是否符合文件。wxss/i //要替换的最后一个字符串const final str='/子页/enjoy _ given/static/CSS/vendor . wxss//获取文件内容let content=compile . assets[file pathname]。source () | |'' content=content。replace (reg,final str)//重写指定的输出模块内容编译。assets[file pathname]={ source(){ return content;},size(){ return content . length;}}}}回调()})}}模块。exports=csspathttransfor查看了很多,实际上是遍历compilation.assets模块。定期更换符合要求的文件。

2)修改网络包配置

var baseWebpackConfig=require(' ./web pack。基地。conf ')var cs path transfer=required('./plugins/cspath transforr。js ')var webpackkconfig=merge(basebpackkconfig,{ module: {.},devtool :配置。建造。生产源图?#source-map' : false,output: {.},plugins: [. //配置插件新的CssPathTransfor(),]})插件编写完成后,执行编译命令

搞定~

如果有更多的需求可以参考《如何写一个插件》

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

版权声明:网络包加载器和插件编写的详细说明是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。