Webpack
1、相关知识点
1.1、import(es6) 与 require(nodejs)
require在node中的用法(加载并且运行module.export对象)
1.路径形式的模块:require('./')
2.核心模块的本质也是文件: require('http'), require('path')
3.加载第三方模块:require('express')
加载规则:既不是核心模块、也不是路径形式的模块
先找到当前文件所处目录中的 node_modules 目录 -> 对应模块 -> package.json -> package.json 文件中的 main 属性(没有该属性就直接找该目录下index文件)
import(es6)的模块系统(静态加载的)
import命令会被 JavaScript 引擎静态分析,编译时加载模块
require是运行时加载模块,只有运行时才知道,同步加载
import()函数,完成动态加载、异步加载
1.2、node中的path模块
path.resolve() 方法将路径或路径片段的序列解析为绝对路径。
path.join() 方法使用平台特定的分隔符作为定界符将所有给定的 path 片段连接在一起,然后规范化生成的路径。
_dirname变量获取当前模块文件所在目录的完整绝对路径(是一个全局变量)
[参考node官网链接?](http://nodejs.cn/api/path.html#path_path_resolve_paths)
1.2.1 相对路径./问题
require中的相对路径./是不能省略的
1.3、正则表达式
自行学习
2、webpack的基本配置参数
2.1、 entry: “./app/entry”, // string | object | array
2.2、output: // webpack 如何输出结果的相关选项
path: path.resolve(__dirname, “dist”), // string
// 所有输出文件的目标路径
// 必须是绝对路径(使用 Node.js 的 path 模块)
filename: "bundle.js", // string // 「入口分块(entry chunk)」的文件名模板
publicPath: "/assets/", // string ??
2.3、module
由于webpack本身只能解析js文件所以要借用各种loader的配置来处理.css .vue .mp4 .png等文件(这里结合一个loader栗子?说明)
css-loader 将css文件解析成js文件 style-loader将解析好的css加载到style标签里面
loader的执行顺序是从右向左执行(测试css-loader style-loader)
postcss-loader autoprefixer 自动加样式前缀 按照策略选中是否加前缀
file-loader url-loader 处理图片,视频的loader (limit 设置大小是否存为base64 )
2.3、resolve 解析
几个经常用到的配置:
1、resolve.alias 创建别名。我们在项目中经常看到如下的用法:
都是这样配置的:
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
*** 需要注意的点就是’$'表示精确匹配,参考官方文档
2、resolve.extensions 自动解析确定的扩展名
我们平时在项目中引入组件或样式等文件时可以省略后缀名就是在这里设置的
resolve: {
extensions: ['.js', '.vue', '.json']
},
2.4、plugin 插件
2.4.1 打包是自动清除上次的dist目录里的文件
使用clean-webpack-plugin 插件: 注意现在插件导出的是exports.CleanWebpackPlugin = CleanWebpackPlugin
所以在配置文件里引用插件是可以用结构复制去接受 : const {CleanWebpackPlugin} = require('clean-webpack-plugin')
2.4.2 校验css样式
安装stylelint stylelint-webpack-plugin stylelint-config-standard
配置如下:
1. 插件引入
const StyleLintPlugin = require('stylelint-webpack-plugin');
2.插件配置
new StyleLintPlugin({
files: ['**/*.css']
})
3.校验规则配置package.json文件
"stylelint": {
"extends": "stylelint-config-standard"
}
2.5、devServer 运行时
- 方法一:
修改package.json文件配置,传递watch参数。如下:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --env.development --config config/webpack_config_common.js",
"build": "webpack --env.prouduction --config config/webpack_config_common.js",
"watch": "webpack --watch --env.prouduction --config config/webpack_config_common.js"
},
缺点:1.不能模拟服务端的一功能(比如请求转发等)。2.不能自动刷新浏览器等
- 方法二:
配置webpack-dev-server , package.jason配置如下:
webpack配置如下:
具体的参数参考官网链接 - 方法三:使用 webpack-dev-middleware + express 中间键
1、安装 webpack-dev-middleware express
2、新建server.js服务器文件如下:
const express = require('express') // 引入express 中间件
const webpack = require('webpack') // 引入webpack模块
const webpackDevMiddleware = require('webpack-dev-middleware') // 引入 webpack-dev-middleware 中间件
const config = require('./config/webpack_config_common') // 引入webpack 配置文件
const complier = webpack(config()) // 用webpack结合这个配置文件随时进行代码的编译
const app = express() // 创建一个node服务器
app.use(webpackDevMiddleware(complier, {})) // 通过中间件关联 webpack打包的文件 和 node服务器
app.listen(3000, ()=>{ // 监听3000端口, 开启服务器
console.log('server is running on localhost:3000')
})
3、配置package.json文件方便启动
踩过的坑:
在node中使用webpack编译命令webpack({}, function),第一个参数必须是对象。所以如果我们项目中的webpack配置文件导出的是一个函数就要写成这个样子哦哦:
2.6、懒加载和chunks
2.7、分环境打包配置(1)(生产、开发、单元测试环境)
1、 webpack.config.js文件导出一个函数并且接受env变量
module.exports = (env, agr) => {
console.log('env变量', env)
let tempObj = {}
if(env.development) {
tempObj = require('./config/webpack_config_dev')
} else if (env.prouduction) {
tempObj = require('./config/webpack_config_pro')
}
return {
mode: 'development',
entry: './src/js/app.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.js'
},
...tempObj,
module: {
rules: [
{
test: /\.css$/i, // 处理css 文件
use: ['style-loader', 'css-loader', {
loader: 'postcss-loader',
options: {
plugins: [require('autoprefixer')]
}
}]
},
{
test: /\.(jpg|jpeg|png)$/, // 处理图片文件
use: [
{
loader: 'url-loader',
options: {
limit: 1000,
outputPath: 'imags',
publicPath: 'dist/imags/'
}
}
]
},
{
test: /\.less$/, // 处理less文件
use: ['style-loader', 'css-loader', 'less-loader',]
},
{
test: /\.(js|jsx)$/i, // 处理es6的语法
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env'
]
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html'
}),
new CleanWebpackPlugin(),
new StyleLintPlugin({
files: ['**/*.css']
})
]
}
}
2. 在package.json文件中传入不同的变量
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --env.development",
"build": "webpack --env.prouduction"
},
3. 新建开发环境和生产环境的配置文件
3.1 开发环境webpack_config_dev.js :
const path = require('path')
module.exports = {
mode: 'development',
entry: path.resolve(__dirname, '../src/js/app.js'),
output: {
path: path.resolve(__dirname, '../dist'),
filename: 'devbundle.js'
},
devtool: 'source-map',
}
3.2 生产环境webpack_config_pro.js:
const path = require('path')
module.exports = {
mode: 'production',
entry: path.resolve(__dirname, '../src/js/app.js'),
output: {
path: path.resolve(__dirname, '../dist'),
filename: 'probundle.min.js'
}
}
2.8、分环境打包配置(2) 通过webpack-merge来实现
1、安装webpack-merge
2、分环境写好不同的配置文件(同2.7)
3、通过webpack-merge的方法把不同的配置merge合并。如下:
const merge = require('webpack-merge')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const StyleLintPlugin = require('stylelint-webpack-plugin')
module.exports = (env, agr) => {
let tempObj = {}
if(env.development) {
tempObj = require('./webpack_config_dev')
} else if (env.prouduction) {
tempObj = require('./webpack_config_pro')
}
return merge(tempObj, {
module: {
rules: [
{
test: /\.css$/i, // 处理css 文件
use: ['style-loader', 'css-loader', {
loader: 'postcss-loader',
options: {
plugins: [require('autoprefixer')]
}
}]
},
{
test: /\.(jpg|jpeg|png)$/, // 处理图片文件
use: [
{
loader: 'url-loader',
options: {
limit: 1000,
outputPath: 'imags',
}
}
]
},
{
test: /\.less$/, // 处理less文件
use: ['style-loader', 'css-loader', 'less-loader',]
},
{
test: /\.(js|jsx)$/i, // 处理es6的语法
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env'
]
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html'
}),
new CleanWebpackPlugin(),
new StyleLintPlugin({
files: ['**/*.css']
})
]
})
}
2.9、将项目中的less sass css 等样式文件抽离出来
1、安装mini-css-extract-plugin
2、使用插件
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
})
3、注意2点
** 打包模式必须是production. 即 ( mode: ‘production’)
** 将style-loader 替换成 MiniCssExtractPlugin.loader
** css打包到css目录下,js打包到js目录下 效果如下
只需要在输出的filenam前加上层级目录就可以了