Webpack
一直只是在码界面,现基于官网文档做一次系统的webpack内容学习
核心概念
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)
入口(entry)
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始(定义打包入口文件路径),默认是./src
。
输出(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist
(定义打包输出地址)。
loader
相当于处理器,对非js或es6+的文件进行解析和转换,使之成为webpack能够打包处理的文件。官网解释:webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
插件(plugins)
loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
使用:1)添加require;2)添加到plugins数组中
模式
模式(mode)指明运行模式,development:开发,production:生产
入口起点
单个入口:entry: string|Array<string>
webpack.config.js
module.exports = {
entry: './src/main.js',
}
// 或者
module.exports = {
entry: {
main: './src/main.js',
}
}
多个文件入口:entry: {[entryChunkName: string]: string|Array<string>}
webpack.config.js
module.exports = {
entry: {
app: './src/main.js',
vendor: './src/vendor.js',
style: ['animate.css']
}
}
输出(output)
配置 output 选项可以控制 webpack 如何向硬盘写入编译文件。注意,即使可以存在多个入口起点,但只指定一个输出配置。
用法
- filename:输出文件名
- path:目标输出目录的绝对路径
module.exports = {
mode: 'development',
entry: {
app: './src/main.js',
},
output: {
// 单文件
// filename: 'bundle.js',
// path: '/dist',
filename: '[name].js',
path: __dirname + '/dist'
}
}
filename
此选项决定了每个输出 bundle 的名称。这些 bundle 将写入到 output.path 选项指定的目录下。
chunkFilename
非入口文件的打包名称
path
目录对应一个绝对路径
path: path.resolve(__dirname, 'dist/assets')
publicPath
此选项指定在浏览器中所引用的「此输出目录对应的公开 URL」
publicPath: "https://cdn.example.com/assets/", // CDN(总是 HTTPS 协议)
publicPath: "//cdn.example.com/assets/", // CDN (协议相同)
publicPath: "/assets/", // 相对于服务(server-relative)
publicPath: "assets/", // 相对于 HTML 页面
publicPath: "../assets/", // 相对于 HTML 页面
publicPath: "", // 相对于 HTML 页面(目录相同)
模式
提供 mode 配置选项,告知 webpack 使用相应模式的内置优化。
loader
文件预处理并转换为可读js,需要配置对应的转换器
示例
module.exports = {
...
module: {
rules: [
{
test: /\.css/,
use: ['style-loader', 'css-loader'], // css-loader解析样式,style-loader注入样式
},
{
test: /\.ts/,
use: 'ts-loader'
},
]
}
}
插件
webpack支柱功能,解决loader无法实现的其他事。
webpack 插件是一个具有 apply 属性的 JavaScript 对象。apply 属性会被 webpack compiler 调用,并且 compiler 对象可在整个编译生命周期访问。
配置
const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过 npm 安装
const webpack = require('webpack'); //访问内置的插件
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
filename: 'my-first-webpack.bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader'
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
})
]
};
module.exports = config;
常用插件
HtmlWebpackPlugin
基于index.html动态引入输出文件。
- title:生成html的title属性值,窗口名称
- filename:生成文件名,默认是index.html
- template:生成html依赖的模版
- inject:插入script标签的位置,默认true,body底部(其他:body,head,false)
cleanWebpackPlugin
编译时清理历史打包文件,用法示例如下:
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
...
plugins: [
new CleanWebpackPlugin(),
]
UglifyjsWebpackPlugin
代码压缩,常用参数:test,include,exclude
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
plugins: [
new UglifyJsPlugin()
]
}
模块解析
resolver 是一个库(library),用于帮助找到模块的绝对路径。
解析路径时会根据模块检索模块下的文件。可以通过resolve.alias给常用模块添加别名,使用resolve.extensions定义接受的文件类型,能够使用户在引入模块时不带扩展:
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'@': path.resolve('src'),
'element': path.resolve('element'),
}
}
模块
主要还是module.rules,每一个rule配置响应的loader(解析器)和test(目标对象正则)
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader',
include: [path.resolve('src')], // 目标目录
exclude: [path.resolve('static'), // 排除目录
},
{
test: /\.(sa|sc|c)ss$/,
use: [
'css-hot-loader',
MiniCssExtractPlugin.loader,
// 'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
'postcss-loader',
'sass-loader',
],
},
]
}
开发中
devServer
webpack-dev-sever插件实现代码的动态编译及自动重载
安装:
npm install --save-dev webpack-dev-server
应用与配置
// package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack --config config/webpack.dev.config.js",
"dev": "webpack-dev-server --config config/webpack.dev.config.js",
"build": "rm -rf ./dist && webpack --config config/webpack.prod.config.js"
},
// webpack.dev.config.js
devServer: {
host: '0.0.0.0', // 域名
overlay: true, // 错误全屏展示
port: 9003, // 端口
historyApiFallback: true, // 404 响应时,重定向
compress: true, // 服务采用gzip压缩
inline: true, // 内联模式
hot: true, // 热更新
headers: {
"X-Custom-Foo": "bar"
}, // 添加响应头
open: true, // 启动时浏览器打开地址
clientLogLevel: 'none', // 阻止调试日志显示
publicPath: '/', // 包文件浏览器访问路径
disableHostCheck: true, // 域名校验
quiet: false, // 是否展示webpack报错信息
proxy: [{ // 代理
context: ['/api', './auth'], // 接口匹配
target: 'https://****‘, // 目标地址
changeOrigin: true, // 修改源
secure: false // 是否接受运行在https上
}],
// 输出的日志信息
stats: {
// 添加 public path 的信息
publicPath: true,
// 添加构建模块信息, 这个日志非常多,关掉
modules: false,
// 添加 children 信息, 非常多
children: false,
// 添加警告
warnings: true
}
},