一、核心概念
- Entry:入口,Webpack执行构建的第一步是从Entry开始,可抽象为输入;
- Module:模块,在Webpack里一切皆模块,一个模块对应一个文件。Webpack会从配置的Entry开始递归找出所有依赖的模块;
- Chunk:代码块,一个Chunk由多个模块组合而成,用于代码合并与分割;
- Loader:模块转换器,用于将模块的原内容按照需求转换为新内容;
- Plugin:扩展插件,在Webpack构建流程中的特定时机注入扩展逻辑,来改变构建结果或者做我们想做的事;
- Output:输出结果,在Webpack经过一系列处理并得出最终想要的代码后输出的结果。
大致流程如下:
Webpack在启动后会从Entry里配置的Module开始,递归解析Entry依赖的所有Module。每找到一个Module,就会根据配置的Loader去找出对应的转换规则,对Module进行转换后,再解析当前Module依赖的Module。这些模块会根据Entry为单位进行分组,一个Entry及其所有依赖的Module被分到一个组内,也就是一个Chunk。最后,Webpack会将所有Chunk转换成文件输出。在整个流程中,Webpack会在恰当的时机执行Plugin里定义的逻辑。
详解Webpack核心概念
(一)、Entry
Entry配置是必填的,如果不填将会导致Webpack报错,退出。
1、context:Webpack在寻找相对路径的文件时会以context为根目录,context默认为执行启动Webpack时所在的当前工作目录。
context: path.resolve(__dirname, '../'),
需要注意的是,context必须是一个绝对路径的字符串。
2、Entry类型:可以为string、array、object三者中任意类型。
- string:
'./app/entry'
、入口模块的文件路径,可以是相对路径; - array:
['./app/entry1','./app/entry2']
、入口模块的文件路径,可以是相对路径; - object:
{a:'./app/entry',b:['./app/entry1','./app/entry2']}
,配置多个路口,每个入口生成一个chunk。
3、Chunk的名称
Webpack会为每个生成的Chunk取一个名称,Chunk的名称和Entry的配置有关。
- 如果Entry是一个string或array,就只会生成一个Chunk,这时Chunk的名称是main;
- 如果Entry是一个object,那么会出现多个Chunk,这时Chunk的名称是object键值对中键的名称。
4、为MPA应用配置Entry
在untils.js文件中添加如下代码逻辑:
// untils.js
const path = require('path')
const glob = require('glob')
const PAGE_PATH = path.resolve(__dirname, '../src/pages');
exports.entries = function() {
var entryFiles = glob.sync(PAGE_PATH + '/*/*.js')
var map = {
}
entryFiles.forEach((filePath) => {
var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'));
map[filename] = filePath;
})
return map;
}
替换webpack.base.config.js
中module.exports中的entry:
entry: untils.entries()
(二)、Output
output是一个object,里面包含一系列配置。
1、filename
output.filename配置输出文件的名称,为string类型。如果只有一个输出文件,则可以将他写为静态不变的:filename:'bundle.js'
;倘若有多个Chunk需要输出,需要借助模板和变量。Webpack会为每个Chunk取一个名称,所以我们可以根据Chunk的名称来区分输出的文件名:filename:'[name].js'
.
2、path
output.path配置输出文件存放在本地的目录,必须是string类型的绝对路径。通常通过Node.js中的path模块去获取绝对路径:path:path.resolve(__dirname,'dist_[hashj]');
3、publicPath
output.publicPath配置发布到线上资源的URL前缀,为string类型。默认值为空字符串’’,即使用相对路径。
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
(三)、Module
1、配置Loader:rules配置模块的读取和解析规则,通常用来配置loader。其类型为数组,数组里的每一项都描述了如何处理部分文件。
- 条件匹配:通过test、include、exclude三个配置项来选中Loader要应用规则的文件;
- 应用规则:对选中的文件通过loader配置项来应用Loader;
module: {
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/, // 命中js文件
loader: 'babel-loader', // 使用babel-loader转换js文件
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] // 只命中src目录下的js文件,加快webpack搜索速度
},
]
}
(四)、Resolve
Webpack在启动后会从配置的入口模块出发找出所有依赖的模块,Resolve配置Webpack如何寻找模块对应的文件。可采用默认模块化标准里的规则去查找,也可以自定义。
1、alias:resolve.alias配置项通过别名来将原导入路径映射为一个新的导入路径;
2、extensions:在导入语句没带文件后缀时,Webpack会自动带上后缀去尝试访问文件是否存在。resolve.extensions用于配置在尝试过程中用到的后缀列表。
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
(五)、Plugin
用于Webpack功能扩展,plugins配置项接收一个数组,数组里的每一项都是一个要使用的Plugin的实例,Plugin需要的参数通过构造函数传入。
配置一个MPA应用的多输出扩展功能。
在utils.js中:
const HtmlWebpackPlugin = require('html-webpack-plugin'); //对每个页面单独打包生成一个新页面的插件
const merge = require('webpack-merge')
// 多页面输出配置
exports.htmlPlugin = function() {
let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')
let arr = []
entryHtml.forEach((filePath) => {
let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
let conf = {
template: filePath,
filename: filename + '.html',
chunks: [filename],
inject: true
}
if(process.env.NODE_ENV === 'production') {
conf = merge(conf, {
chunks: ['manifest', 'vendor', filename],
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
chunksSortMode: 'dependency'
})
}
arr.push(new HtmlWebpackPlugin(conf))
})
return arr
}
在webpack.dev.conf.js中如下操作:
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
// new HtmlWebpackPlugin({
// filename: 'index.html',
// template: 'index.html',
// inject: true,
// chunks: ['app']
// }),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
].concat(utils.htmlPlugin()) // 重点
学习于吴浩麟的《深入浅出Webpack》
MPA和SPA是什么?:可以看下这个哦
码云地址:如何使用vue-cli+webpack搭建一个MPA应用
转载:https://blog.csdn.net/The_upside_of_down/article/details/115794834