你们好,以前出了一篇面试篇webpack入门,这篇文章继续介绍接下来更深刻东西。javascript
讲道理你们都是直接import一个loader或者使用webpack内置的loader的。css
若是调试本身的loader,应该以下写法:vue
//webpack.config.js
const path = require("path");
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: path.resolve("loader.js"),
options: {
test: 'apple'
}
}
]
}
]
}
};
复制代码
其实和正常载入loader同样,只是这里指向的是本地文件的路径。java
path.resolve('loader.js') 得出路径node
/Users/kev1nzh/Desktop/my/webpack/loader.jsreact
在使用一个loader的时候,loader会接收你正则匹配的资源文件(如上,全部js文件)的字符串。
loader经过代码转化模块后,最后返回传递出去。
复制代码
当使用多个loader的时候,从传入loader数组的最后一个开始反向传入资源文件字符串。webpack
最后一个loader接收最原始的资源文件字符串,转化后传入下一个lodaer。ios
中间的loader接收上一个loader,转化后传入下一个。es6
第一个loader最后接收转化,并传出全部loader处理完的资源文件字符串。web
{
test: /\.css$/,
use: [
{
loader: 'css-loader'
},
{
loader: 'style-loader'
},
]
}
//style-loader接收全部css的文件,转化完再传给css-loader,转化完后再怼出来。
复制代码
loader-utils, schema-utils是webpack的loader工具库,有不少便捷的方法能够调用。
const { getOptions,stringifyRequest, parseQuery } = require("loader-utils");
const validateOptions = require("schema-utils");
const schema = {
type: "object",
properties: {
test: {
type: "string"
}
}
};
module.exports = function(source) {
//getOptions 用于在loader里获取传入的options,返回的是对象值。
const options = getOptions(this);
// stringifyRequest转换路径,避免require()或impot时使用的绝对路径
stringifyRequest(this, "./test.js"); // Result => "\"./test.js\""
//parseQuery获取query参数的,这个很简单就不说啦
parseQuery('?name=kev&age=14') // Result => {name: 'kev', age: '14'}
//验证参数的类型是否正确。
validateOptions(schema, options, "loader");
};
复制代码
总算到手写环节了!!!!
//webapck.config.js
const path = require("path");
module.exports = {
entry: "./src",
output: {
path: path.resolve(__dirname, "dist"),
filename: "package.js"
},
mode: "production",
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: path.resolve("loader.js"),
options: {
work: '996',
sick: 'ICU',
}
}
]
}
]
}
};
复制代码
首先载入工具库,为了后续使用。
第一步先验证options是否符合类型,
第二步获取参数,而后替换传入的资源文件字符串。
//loader.js
const { getOptions } = require("loader-utils");
const validateOptions = require("schema-utils");
const schema = {
type: "object",
properties: {
work: {
type: 'String'
},
sick: {
type: 'String'
}
}
};
module.exports = function(source) {
const options = getOptions(this);
validateOptions(schema, options, 'loader');
const {work, sick} = options;
source = source.replace(/\[work\]/g, work).replace(/\[sick\]/g, sick);
return `export default ${JSON.stringify(source)}`;
};
复制代码
展现下要转换的js。
// src/index.js
console.log('工做[work] 生病[sick] 加班不规范 亲人两行泪');
复制代码
最后在命令行,webpack!!!!!
const index = require('./index');
const console = require('./console');
//index.js
const axios = require('./scripts/debounce.js'');
const moment = require('moment');
// do something
复制代码
// ./src/moment.js
const moment = require('moment');
console.log(moment().format('MMMM Do YYYY, h:mm:ss a'))
// ./index.js
const momentJs = require('./src/moment');
console.log(123);
复制代码
如上代码,咱们打包一下试试看。
webpack4.x的分离代码方法,以前的CommonsChunkPlugin插件已被移除。 此模块开箱即用,默认状况下,它仅影响按需块,由于更改初始块会影响HTML文件应包含的脚本标记以运行项目。
webpack将根据如下条件自动拆分块:
让咱们看下代码如何实现!
module.exports = {
//...
optimization: {
splitChunks: {
chunks: 'initial', //选择哪些模块须要优化, 参数为 all、async、initial
minSize: 30000, // 要生成的块的最小数
maxSize: 0, //要生成的块的最大数
minChunks: 2, // 分割前共享模块的最小块数
maxAsyncRequests: 5, //按需加载时的最大并行请求数
maxInitialRequests: 3, // 入口的最大并行请求数
automaticNameDelimiter: '~', //指定生成文件名当中的分隔符
name: true, //拆分块的名称
cacheGroups: { //缓存组
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
};
复制代码
面试系列第一篇: 面试官:你知道Callback Hell(回调地狱)吗?
面试系列第二篇: 面试官:react和vue有什么区别吗?
面试系列第三篇: 面试官:你了解es6的知识吗?
面试系列第四篇: 面试官:你了解Webpack吗?