关于webpack构建流程,loader和plugin的区别与开发

1、Webpack 的构建流程主要有哪些环节?如果可以请尽可能详尽的描述 Webpack 打包的整个过程。

根据配置文件里entry找到打包入口文件
顺着入口文件代码里的import或require之类的语句,解析推断文件所依赖的资源模块
分别去解析每个资源模块对应的依赖,最后形成一颗依赖树,
递归依赖树,找到每个节点对应的资源文件,
根据配置文件 rules 属性,找到资源模块所对应的加载器,
交给对应的加载器加载对应的资源模块,
最后将加载以后的结果放入到bundle.js打包结果里,
实现整个项目的打包。

2、Loader 和 Plugin 有哪些不同?请描述一下开发 Loader 和 Plugin 的思路。

Loader 和 Plugin 的不同

  • loader是资源加载器,实现资源模块的转换和加载,编译转换类 css-loader,文件操作类 file-loader、url-loader,代码检查类 eslint-loader,负责资源文件从输入到输出的资源转换,对于同一个资源可以使用多个loader,类似于管道概念
  • Plugin 解决除了资源加载之外其他自动化工作(打包之前清除 dist 目录、拷贝静态文件、压缩代码等等)

开发loader的思路

每个webpack的loader需要导出一个函数 这个函数是对加载到的资源的处理过程 输入是加载到的资源文件的内容 输出是加工之后的结果

	const marked = require('marked')
	module.exports = source => {//接收到的资源文件
	  // console.log(source)
	  // return 'console.log("hello ~")'
	  const html = marked(source)
	
	  //方式一:第一,输出标准的 JS 代码,让打包结果的代码能正常执行;
	  return html
	  return `export default ${JSON.stringify(html)}`
	
	  //方式二: 输出处理结果,交给下一个 loader 进一步处理成 JS 代码
	  //返回 html 字符串交给下一个 loader 处理
	  return html
	}

在 webpack.config.js 中使用 loader,配置 module.rules ,其中 use 除了可以使用模块名称,也可以使用模块路径

	const path = require('path')
	
	module.exports = {
	  mode: 'none',
	  entry: './src/main.js',
	  output: {
	    filename: 'bundle.js',
	    path: path.join(__dirname, 'dist'),
	    publicPath: 'dist/'
	  },
	  module: {
	    rules: [
	      {
	        test: /.md$/,
	        use: [//输出处理结果交给下一个laoder处理
	          'html-loader',
	          './markdown-loader'
	        ]
	      }
	    ]
	  }
	}

开发plugin的思路

plugin 是通过在生命周期的钩子中挂载函数实现扩展,我们可以在不同的事件节点上挂载不同的任务,就可以扩展一个插件,插件必须是一个函数或者是一个包含 apply 方法的对象,一般可以把插件定义为一个类型,在类型中定义一个 apply 方法
apply 方法接收一个 compiler对象 参数,包含了这次构建的所有配置信息,
通过这个对象注册钩子函数
通过 compiler.hooks.emit.tap 注册钩子函数(emit也可以为其他事件),
钩子函数第一个参数为插件名称,
第二个参数 compilation函数 为此次打包的上下文,
根据 compilation.assets[name].source() 就可以拿到此次打包的资源的内容,
然后做一些相应的逻辑处理

class MyPlugin {
  apply (compiler) {
    console.log('MyPlugin 启动')
    compiler.hooks.emit.tap('MyPlugin', compilation => {
      // compilation => 可以理解为此次打包的上下文
      for (const name in compilation.assets) {
        // console.log(name)
        // console.log(compilation.assets[name].source())
        if (name.endsWith('.js')) {
          const contents = compilation.assets[name].source()//文件内容
          const withoutComments = contents.replace(/\/\*\*+\*\//g, '')
          compilation.assets[name] = {
            source: () => withoutComments, //返回新的内容
            size: () => withoutComments.length //返回新的内容的长度
          }
        }
      }
    })
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值