Webpack学习笔记
webpack - 项目优化
webpack实现原理
webpack - loader
webpack - plugin
webpack - 项目优化2
resolveLoader: {
// loader查找规则
modules: [path.resolve(__dirname, 'node_modules'),path.resolve(__dirname, 'loaders')],
// loader别名
alias: {
txt: path.resolve(__dirname, 'loaders', 'txt.js')
}
},
module: {
rules: [
{
exclude: /node_modules/,
test: /\.txt$/,
use: [ path.resolve(__dirname, 'loaders', 'txt.js') ]
},
{
exclude: /node_modules/,
test: /\.txt$/,
use: 'txt'
},
{
test: /\.less$/,
use: [ 'style.js', 'less.js' ]
}
-
exclude 不作用于此目录下文件
-
绝对路径、alias别名、loader查找规则、第三方库(node_modules) loader的4种引入方式
-
pre -> normal(默认) -> inline -> post,loader的类型及执行顺序
{
test: /\.less$/,
use: [ 'style.js', 'less.js' ],
enforce: 'pre' // pre loader
}
- loader.pitch 它是正向执行的(与loader组成一个洋葱),如果它有返回值,将会终止后续loader的执行
loader.pitch = function () { console.log('我会最早执行,即洋葱的前半部分'); return 'xxx' }
- inline 只能在代码中使用
require('!inline-loader!./a.js') // 不再匹配其它loader
require('-inline-loader!./a.js') // 把pre和normal屏蔽掉
require('inline-loader!./a.js') // 没有normal
options
{
exclude: /node_modules/,
test: /\.txt$/,
use: {
loader: 'txt',
options: { content: '明治维新燃油费' } // 为loader配置options
}
},
let loaderUtils = require('loader-utils')
module.exports = function (source) {
// this上下文相关属性和方法参见 https://www.webpackjs.com/api/loaders/
// 读取webpack.config.js中配置的options
// console.log(this.query)
// let content = this.query && this.query.content || '统一换成这个'
// 好鸡肋,为什么要用
// console.log(loaderUtils.getOptions(this))
let query = loaderUtils.getOptions(this)
let content = query && query.content || '统一换成这个'
// return `module.exports = "${content}"`
let cb = this.async() // 将Loader变为异步loader
setTimeout(() => cb(`module.exports = "${content}"`), 2000)
}
打包后
"./common/xx.txt": eval("module.exports = \"明治维新燃油费\"\n\n//# sourceURL=webpack:///./common/xx.txt?");
参数校验
module: {
rules: [
{
test: /\.html/,
use: {
loader: 'html-minify-loader.js',
options: {
comments: false
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './template/index.html'
})
// 本质上是require了index.html,所以loader会起作用
// 可以配置嵌入的js是否有?hash、是否去掉”、是否消除空白等
]
// html-minify-loader.js
let Minimize = require('minimize') // 代码压缩
let schemaUtils = require('schema-utils') // 参数校验
function loader (source) {
let porps = {
"type": "object",
"properties": {
"comments": {
"type": "boolean"
}
}
}
// 验证不通过会抛出异常
schemaUtils(porps, this.query, 'html-minify-loader')
let mini = new Minimize(this.query)
source = mini.parse(source);
return `module.exports = ${JSON.stringify(source)}`
}
module.exports = loader
根据模板生成入口html文件
module: {
rules: [
{
test: /\.html/,
use: {
loader: 'html-layout-loader.js',
options: {
template: path.resolve(__dirname, 'template', 'index.html'),
reg: /\{\{content\}\}/
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'home.html',
template: './template/home.html'
}),
new HtmlWebpackPlugin({
filename: 'login.html',
template: './template/login.html'
})
]
// html-layout-loader.js
let fs = require('fs')
// 根据模板生成入口html文件
function loader (source) {
let {template, reg} = this.query
let cb = this.async()
fs.readFile(template, 'utf8', function (err, data) {
source = data.replace(reg, source)
cb(err, `module.exports = ${JSON.stringify(source)}`)
})
// return `module.exports = ${JSON.stringify(source)}`
}
module.exports = loader
npx webpack --watch 对模板进行watch
// html-layout-loader.js
...
// webpack --watch 时,对模板也进行实时打包
this.addDependency(template)
...
处理图片资源
rules: [
{
test: /\.png$/,
use: {
loader: 'file-loader.js', // 处理引用的图片路径
}
}
]
// file-loader.js
let loaderUtils = require('loader-utils')
function loader (source) {
// 生成新文件名,8位哈希值.原名.原扩展名
let name = loaderUtils.interpolateName(this, `[hash:8].[name].[ext]`, { content: '哈希摘要的依据' })
// 发射到目标文件根目录
this.emitFile(name, source)
return `module.exports = "${name}"`
}
loader.raw = true; // 表示source是二进制(buffer)
module.exports = loader
打包后dist目标下出现f371901e.avatar.png
,bundle中"./common/avatar.png":(function(module, exports) { eval("module.exports = \"f371901e.avatar.png\"...
- 小于50k的文件base54化
rules: [
{
test: /\.png$/,
use: {
loader: 'url-loader.js', // base64化小图
options: { minisize: 50 * 1024 }
}
}
]
// url-loader.js
const mime = require("mime");
function loader (source) {
let { minisize } = this.query
if (source.length > minisize) {
return require('./file-loader').call(this, source)
} else {
// 小于指定大小,base64化图片
let type = mime.getType(this.resourcePath)
return `module.exports = "data:${type};base64,${source.toString('base64')}"`
}
}
loader.raw = true; // 表示source是二进制(buffer)
module.exports = loader
打包后dist/bundle.js中"./common/avatar.png":(function(module, exports) { eval("module.exports = \"data:image/png;base64,iVBORw...
网友评论