webpack的核心概念和配置
一。entry:资源的入口
1. 字符串类型入口
module.exports = {
entry: './src/index.js', // 字符串类型
output:{
filename: 'bundle.js'
},
mode: 'development',
}
2. 数组类型入口
module.exports = {
// 传入一个数组的作用是将多个资源预先合并,在打包时webpack会将数组中的最后一个元素作为实际的入口路径
entry: ['babel-polyfill', './src/index.js'] // 数组类型
output:{
filename: 'bundle.js'
},
mode: 'development',
}
3. 对象类型入口(定义多入口,必须使用对象的形式)
module.exports = {
entry: {
index: './src/index.js', // 对象类型
lib: './src/lib.js',
},
output:{
filename: 'bundle.js'
},
mode: 'development',
}
module.exports = {
entry: {
index: ['babel-polyfill', './src/index.js'], // 对象类型
lib: './src/lib.js',
}
output:{
filename: 'bundle.js'
},
mode: 'development',
}
4. 函数类型入口(返回上面介绍的任何配置形式即可)
module.exports = {
entry: {
index: () => './src/index.js', // 函数类型
lib: './src/lib.js',
},
output:{
filename: 'bundle.js'
},
mode: 'development',
}
5. 提取vendor(指提取工程所使用的库,框架等第三方模块计中打包而产生的bundle。
module.exports = {
entry: {
app: './src/index.js',
vendor: ['react', 'react-dom', 'react-router'],
},
output:{
filename: 'bundle.js'
},
mode: 'development',
}
二。资源的出口
例子:
const path = require('path')
module.exports = {
entry: {
index: './src/index.js',
},
output:{
filename: 'bundle.js',
path: path.join(__dirname, 'assets'),
publicPath: '/dist/,
},
mode: 'development',
}
1. filename
作用:控制输出资源的文件名,形式为字符串
// 可以为相对路径
module.exports = {
entry: {
index: './src/app.js',
},
output:{
filename: './js/bundle.js'
},
mode: 'development',
}
// 多入口情况时,动态生成文件名
// 最后生成的名称分别为:app.js 和 vendor.js
module.exports = {
entry: {
index: './src/app.js',
vendor: './src/vendor.js',
},
output:{
filename: '[name].js'
},
mode: 'development',
}
// 多入口情况时,动态生成文件名,名称后面要加hash码
// 最后生成的名称分别为:app@432412432423.js 和 vendor@32143141412.js
module.exports = {
entry: {
index: './src/app.js',
vendor: './src/vendor.js',
},
output:{
filename: '[name]@【chunkhash].js'
},
mode: 'development',
}
2. path:指定资源输出的位置,要求值必须为绝对路径
// 将资源输出位置设置为工程的dist目录,webpack4之后,output.path已经默认为dist目录
module.exports = {
entry: {
index: './src/app.js',
},
output:{
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
mode: 'development',
}
3. publicPath:用来指定资源的请求位置
// 1. HTML相关:我们可以将 publicPath 指定为HTML的相对路径,在请求这些资源时会以当前页面HTML所在路径加上相对路径构成实际请求的 URL。
// 假设当前HTML地址为 https://www.baidu.com/app/index.html
// 异步加载的资源名为 0.chunk.js
publicPath: "" // 实际路径 https://www.baidu.com/app/0.chunk.js
publicPath: "./js" // 实际路径 https://www.baidu.com/app/js/0.chunk.js
publicPath: "../assets" // 实际路径 https://www.baidu.com/assets/0.chunk.js
// 2. HOST 相关
// 若 publicPath 的值以 "/" 开始,则代表此时 publicPath 是以当前页面的 host name 为基础路径的
// 假设当前HTML地址为 https://www.baidu.com/app/index.html
// 异步加载的资源名为 0.chunk.js
publicPath: "/" // 实际路径 https://www.baidu.com/0.chunk.js
publicPath: "/js/" // 实际路径 https://www.baidu.com/js/0.chunk.js
publicPath: "/dist/" // 实际路径 https://www.baidu.com/dist/0.chunk.js
// 3. CDN 相关
// 使用绝对路径,因为其域名和当前页面域名不一致,需要绝对路径的形式进行指定
// 假设当前HTML地址为 https://www.baidu.com/app/index.html
// 异步加载的资源名为 0.chunk.js
publicPath: "http://cdn.com/" // 实际路径 http://cdn.com/0.chunk.js
publicPath: "https://cdn.com/" // 实际路径 https://cdn.com/0.chunk.js
publicPath: "//cdn.com/assets/" // 实际路径 //cdn.com/assets/0.chunk.js
三。loader:预处理器
三。一 基本配置:
// 先下载这个模块 npm install css-loader
module.exports = {
module: {
rules:[
{
test: /\.css$/,
use: ['css-loader'],
}
]
}
}
1. test
可接收一个正则表达式或者一个元素为正则表达式的数组,只有正则匹配上的模块才会使用这条规则。以上是匹配所有以 .css 结尾的文件
2. use
可接收一个数组,数组包含该规则所使用的 loader。
2.1 配置项 option
2.1.1 loader :指定模块的名称
2.1.2 options:
rules:[
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options:{
// css-loaer 配置项
}
}
]
}
]
3. exculde(优先级比 include 高)
用来排除指定目录下的模块,可接收正则表示式或者字符串(文件绝对路径),以及由它们组成的数组
4. include
用来包含指定目录下的模块,可接收正则表示式或者字符串(文件绝对路径),以及由它们组成的数组
rules:[
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
exclude: /node_modules/, // 排除的优先级更高
include: /node_modules\/awesome-ui/,
}
]
三。二 常用的 loader
1. babel-loader
babel-loader 用来处理 ES6+ 并将其编译为 ES5
// npm install babel-loader @babel/core @babel/preset-env
rules:[
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true, // 启动缓存机制,防止重复二次编译。
presets: [{
'env', {
modules: false,
}
}]
}
},
}
]
2. ts-loader
将 Typescript 转化为 ES5
// npm install ts-loader typescript
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
}
]
// 需要注意的是,Typescript 本身的配置并不在 ts-loader 中,而是必须要放在工程目录下的 tsconfig.json 中。如:
{
"compilerOptions":{
"target": "es5",
"sourceMap": true,
}
}
3. html-loader
用于将 HTML 文件转化为字符串并进行格式化,这使得我们可以把一个 HTML 片段通过 JS 加载进来
// npm install html-loader
rules:[
{
test: /\.html$/,
use: 'html-loader',
}
]
// 使用示例
// header.html
<header>
<h1> this is a header. </h1>
</header>
// index.js
import headerHtml from './header.html'
document.write(headerHtml);
// header.html 将会转化为字符串,并通过 document.write 插入页面中
四。插件(plugin)
1. extract-text-webpack-plugin(适用于webpack4之前版本)
专门用来提取样式到 css 文件的
// webpack.config.js
// npm install extract-text-webpack-pluin
const ExtractTextPlugin = require('extract-text-webpack-plugin')
// 单个 css 样式
module.exports = {
entry: './app.js', // 字符串类型
output:{
filename: 'bundle.js'
},
mode: 'development',
module:{
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader', // 指定当插件无法提取样式时所采取的loader
use: 'css-loader',
})
}
]
},
plugins:[
new ExtractTextPlugin("bundle.css")
]
}
// 多个 css 样式
module.exports = {
entry: {
'./src/scripts/foo.js',
'./src/scripts/bar.js',
}
output:{
filename: '[name].js'
},
mode: 'development',
module:{
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader',
})
}
]
},
plugins:[
new ExtractTextPlugin("[name].css") // 这里名称和出口资源的一样
]
}
2. mini-css-extract-plugin(webpack4以后的版本,以前是用不了的)
专门用来提取样式到 css 文件的,并且支持按需加载
// npm install mini-css-extract-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
entry: './app.js', // 字符串类型
output:{
filename: '[name].js'
},
mode: 'development',
module:{
rules: [
{
test: /\.css$/,
use: [{
loader: MiniCssExtractPlugin.loader,
options: {
publickPath: '../',
}
},
'css-loader'
]
}
]
},
plugins:[
new MiniCssExtractPlugin({
filename: '[name].css',
chukFilename: '[id].css',
})
]
}