上篇文章手写简易打包器的功能是不完善的,比如,只支持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
网友评论