深入webpack之loader原理

上篇文章手写简易打包器的功能是不完善的,比如,只支持JS文件,连CSS都不支持 :)

如何加载CSS?

思路

  • 我们的打包器只支持JS
  • 我们想要加载CSS
  • 如果把CSS变成JS那么就可以加载CSS啦

怎么把CSS变成JS?

在获取依赖文件内容的时候对于不同文件类型做一些小的处理

// 获取文件内容,将内容放至 depRelation
  let code = readFileSync(filepath).toString()
  if(/\.css$/.test(filepath)){ // 如果文件路径以 .css 结尾
    // 把css改造成js 
    code = `
      const str = ${JSON.stringify(code)}
      if(document){
        // 生成style标签
        const style = document.createElement('style')
        style.innerHTML = str
        // 将style标签插入head
        document.head.appendChild(style)
      }
      export default str
    ` 
  }
  const { code: es5Code } = babel.transform(code, {
    presets: ['@babel/preset-env']
  })

最后再将bundle.js引入index.html,样式即可生效

把刚才代码优化成css-loader

新建css-loader.js

// css-loader.js
const transform = code =>  `
      con st str = ${JSON.stringify(code)}
      if(document){
          // 生成style标签
          const style = document.createElement('style')
          style.innerHTML = str
          // 将style标签插入head
          document.head.appendChild(style)
      }
      export default str
`

export default transform

这个函数实际就是将css代码 变成js代码

然后在打包文件里面引入它

// bundle.js
  if(/\.css$/.test(filepath)){ // 如果文件路径以 .css 结尾
    code = require('./css-loader.js')(code)
  }

运行发现报错了,原来是node不识别export default transform的写法,需要改成这

// 避免export关键字
module.exports = transform

搞定,这下可以使用自己的css-loader加载css文件了

总结:所以loader到底是什么

  • 一个loader可以是一个普通的函数
  • loader也可以是一个异步函数
    async function transform(code) {
      const code2 = await doSomting(code)
      return code2
    }
    module.exports = transform // 旧版本Node.js不支持export关键字
    

另外,为什么使用require而不是import,主要是为了方便动态加载,且旧版本Node.js只能支持require

webpack到底有多少个loader

  • 这里有官网整理的推荐列表
  • 这里有社区整理的推荐列表

你可能感兴趣的:(深入webpack之loader原理)