如何加载css文件

  1. 现在可以加载js
  2. 如果能把css转变为js,那么就可以加载css了

如将css 转为 js?
很简单,只需要将code方法改为js插入css即可

  1. let code = readFileSync(filepath).toString();
  2. if (/\.css$/.test(filepath)) {
  3. // 如果文件路径以 .css 结尾,则处理为style插入head中
  4. code = `
  5. const str = ${JSON.stringify(code)}
  6. if(document){
  7. const style = document.createElement('style')
  8. style.innerHTML = str
  9. document.head.appendChild(style)
  10. }
  11. export default str
  12. `;
  13. }

image.png

把上述代码重构为css-loader

loader是什么

  • 一个 loader 可以是一个普通函数

    1. function transform(code){
    2. const code2 = doSomething(code)
    3. return code2
    4. }
    5. module.exports = transform // 用 module 是为了兼容 Node.js
  • 一个 loader 也可以是一个异步函数

    1. async function transform(code){
    2. const code2 = await doSomething(code)
    3. return code2
    4. }
    5. module.exports = transform // 旧版本 Node.js 不支持 export 关键字

    将代码单独提取出来即可

    1. if (/\.css$/.test(filepath)) {
    2. // 如果文件路径以 .css 结尾
    3. code = require("./loaders/css-loader.js")(code);
    4. }

    单一职责优化

  • css-loader 负责转义代码

  • style-loader 负责插入代码

image.png
理论上可行,但是style-loader并不完全,需要参考webpack源码

style-loader 不是转译

  • sass-loader、less-loader 这些 loader 是把代码从一种语言转译为另一种
  • 因此将这样的 loader 连接起来不会出问题
  • 但 style-loader 是在插入代码,不是转译,所以需要寻找插入时机和插入位置
  • 插入代码的时机应该是在获取到 css-loader 的结果之后
  • 插入代码的位置应该是在就代码的下面

Webpack 官方 style-loader 的思路

  • style-loader 在 pitch 钩子里通过 css-loader 来 require 文件内容
  • 然后在文件内容后面添加 injectStylesIntoStyleTag(content, …) 代码