1. 搭建 webpack 基本环境
1.1 webpack
webpack是 是一个现代 JavaScript应用程序的静态模块打包工具,可以分析你的项目依赖的模块以及一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并生成一个或多个 bundle,将其打包为合适的格式以供浏览器使用.
1.2 初始化项目
npm init -y
1.3 安装webpack
- 安装node
是否安装成功
node -v
npm -v
复制代码
- 安装nrm
//当使用官方npm源安装各种包比较慢的时候,建议下载nrm(npm源管理器)快速切换不同npm源地址。
npm install nrm -g
//查看可选的源
nrm ls
//建议切换到淘宝镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org
nrm use taobao
//添加公司私有npm源,registry是npm源名 url是源的地址
nrm add <registry> <url>
//删除
nrm del <registry>
复制代码
- 安装webpack
//不建议全局安装,这样每个项目可以根据需求安装不同的webpack
//webpack-cli是webpack的命令行,webpack4.0版本以上,把webpack和webpack-cli分离开了,安装了webpack-cli才能运行webpack相关的命令
cnpm install webpack webpack-cli -g
webpack -v
//本地安装并判断是否安装成功
cnpm install webpack webpack-cli -D
npx webpack -v
复制代码
1.3 webpack 打包构建项目
- project
webpack-demo
|- package.json
|- package-lock.json
|- webpack.config.js
|- postcss.config.js
+ |- /src
+ |- css
+ |- js
+ |- images
+ |- index.js
+ |- index.html
+ |- /dist
+ |- bundle.js
+ |- index.html
+ |- images
复制代码
- npm指定入口和出口文件路径(不建议)
//webpack会默认把index.js打包到./dist/main.js
npx webpack ./src/index.js --mode development
//指定入口文件和出口文件路径
npx webpack ./src/index.js -o ./dist/bundle.js --mode development
复制代码
- 在项目文件下创建webpack.config.js文件,指定入口文件和出口文件的路径
var path = require('path')
module.exports = {
mode: 'production', //两种模式,开发模式和生产模式(会把出口文件压缩)
entry: './src/index.js', //入口文件
output: {
path: path.resolve(__dirname, './dist'), //出口文件
//path: path.jion(_dirname, './dist')
filename: 'bundle.js'
}
}
复制代码
在npm运行npx webpack进行打包构建
2. webpack基础配置
2.1 loaders
webpack默认只能打包处理JS类型文件,如果要处理非js类型文件,如后缀为.css/.less/.scss/.png/.vue等的文件,需要手动安装第三方loader加载器来预处理文件
2.1.1 加载css文件
- 安装
npm i style-loader css-loader -D
复制代码
- 在webpack.config.js文件中
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
//加载规则,从上到下,从右到左
//css-loader会把多个css文件合成一段css,style-loader会把这段css挂载在内存html页面的header元素上
}
]
}
复制代码
2.1.2 加载less文件
- 安装
npm i less less-loader -D
复制代码
- 在webpack.config.js文件中
module: {
rules: [
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
]
}
复制代码
2.1.3 加载scss文件
- 安装
npm i sass-loader -D
//建议用cnpm下载sass-loader,npm基本下载不来。
//若npm下载了依赖包,后期报错显示没有,需重新下载,可能使用npm和cnpm命令起来冲突。
//需要把node_modules文件删除,在npm上cnpm i 重装
cnpm i sass-loader -D
复制代码
- 在webpack.config.js文件中
module: {
rules: [
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
}
复制代码
2.1.4 自动添加css3前缀
- 安装
npm i postcss-loader -D
npm i autoprefixer -D
复制代码
- 在项目根目录下新建postcss.config.js文件
module.exports = {
plugins: [
require('autoprefixer')
]
}
复制代码
- 在webpack.config.js文件中
module: {
rules: [
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2, //如果sass文件里还引入了另外一个sass文件,另一个文件还会从最后一个loader向上解析。如果不加,就直接从css-loader开始解析。// 0 => no loaders (default); 1 => postcss-loader; 2 => postcss-loader, sass-loader
modules: true//开启css的模块打包。css样式不会和其他模块发生耦合和冲突
}
},
'postcss-loader',//配置在css-loader后,在sass|less|stylus-loader 之前
'sass-loader'
]
},
]
}
复制代码
2.1.5 加载图片、字体、媒体文件
- 安装
//url-loader 功能与 file-loader类似,只是有文件大小的限制。如果文件小于限制的大小,则会返回 base64 编码。
npm i url-loader -D
复制代码
- 在webpack.config.js文件中
module: {
rules: [
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
name: '[name]_[hash:8].[ext]',
limit: 32000
}
}
]
},
{
test: /\.(ttf|eot|svg|woff|woff2)$/,
use: ['url-loader']
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)$/,
use: [
{
loader: 'url-loader',
options: {
name: '[name]_[hash:8].[ext]',
limit: 32000
}
}
]
}
]
}
复制代码
2.2 plugins
可以在webpack运行到某个时刻的时候,帮你做一些事情
2.2.1 html-webpack-plugin:在打包结束后,在dist目录中自动生成一个html文件,并把打包生成的js自动引入到这个html文件中
- 安装
npm i html-webpack-plugin -D
复制代码
- 在webpack.config.js中
var path = require('path')
var htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
// path: path.jion(_dirname, './dist'),
filename: 'bundle.js'
},
plugins: [ //插件配置的节点
new htmlWebpackPlugin({
template: path.resolve(__dirname, './dist/index.html'),
filename: 'index.html'
})
]
}
复制代码
2.2.2 clean-webpack-plugin:自动清除上一次打包的dist文件
- 安装
npm i clean-webpack-plugin -D
复制代码
- 在webpack.config.js中
var path = require('path')
var htmlWebpackPlugin = require('html-webpack-plugin')
var cleanWebpackPlugin = require('clean-webpack-plugin')
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
// path: path.jion(_dirname, './dist'),
filename: 'bundle.js'
},
plugins: [ //插件配置的节点
new htmlWebpackPlugin({
template: path.resolve(__dirname, './dist/index.html'),
filename: 'index.html'
}),
new cleanWebpackPlugin()
]
}
复制代码
2.3 打包多个入口文件时的配置
在webpack.config.js文件中
var path = require('path')
var htmlWebpackPlugin = require('html-webpack-plugin')
var cleanWebpackPlugin = require('clean-webpack-plugin')
module.exports = {
mode: 'development',
entry: {
main: './src/index.js',
bundle: './src/index.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].js', //main => main.js bundle => bundle.js
publicPath: 'http://cdn.com.cn', //将注入到html中的js文件前面加上地址
},
plugins: [ //插件配置的节点
new htmlWebpackPlugin({
template: path.resolve(__dirname, './dist/index.html'),
filename: 'index.html'
}),
new cleanWebpackPlugin()
]
}
复制代码
2.4 SourceMap:打包编译后的文件和源文件的映射关系,用于开发者调试用
在webpack.config.js文件中
module.exports = {
mode: 'development',
devtool: 'cheap-module-eval-source-map',
//devtool:'none',//在开发者模式下,默认开启sourcemap,将其关闭
//devtool:'source-map'//开启映射打包会变慢,同时生成.map文件
//devtool:'inline-source-map'//不单独生成.map文件,会将生成的映射文件以base64的形式插入到打包后的js文件的底部
//devtool:'cheap-inline-source-map'//代码出错提示不用精确显示第几行的第几个字符出错,只显示第几行出错,会提高一些性能
//devtool:'cheap-module-inline-source-map'//不仅管自己的业务代码出错,也管第三方模块和loader的一些报错
//devtool:'eval'//执行效率最快,性能最好,但是针对比较复杂的代码的情况下,提示内容不全面
//devtool: 'cheap-module-eval-source-map',//在开发环境推荐使用,提示比较全,打包速度比较快
//devtool: 'cheap-module-source-map',//在生产环境中推荐使用,提示效果会好一些
}
复制代码
2.3 webapck-dev-server:实现自动打包编译功能(将dist文件托管到内存中),并开启热更新功能
- 安装
npm i webpack-dev-server -D
复制代码
- 方法一
//1.在package.json文件
//由于webpack-dev-server是本地安装,无法作为脚本命令,在powershell终端运行(只有全局-g安装才可以),需要在package.json的scripts中配置要运行时的一些命令
"scripts": {
"dev": "webpack-dev-server --open --port 3000 --contentBase dist --hot"
},
//3.在npm运行`npm run dev`就可以进行自动打包编译
复制代码
- 方法二
//1.在package.json文件
"scripts": {
"dev": "webpack-dev-server"
},
//2.在webpack.config.js文件中
var webpack = require('webpack')
module.exports = {
plugins: [ //配置插件的节点
new webpack.HotModuleReplacementPlugin() //开启热更新
],
devServer: {
open: true, //自动打开浏览器
port: 3000, //开发服务器监听的端口
contentBase: './dist', //:配置开发服务运行时的文件根目录
hot: true, //开启热更新
hotOnly: true
}
}
//3.在npm运行`npm run dev`就可以进行自动打包编译
复制代码
- 方法三
//1.在webpack.config.js文件中
var webpack = require('webpack')
module.exports = {
plugins: [ //配置插件的节点
new webpack.HotModuleReplacementPlugin() //开启热更新
],
devServer: {
open: true, //自动打开浏览器
port: 3000, //开发服务器监听的端口
contentBase: './dist', //:配置开发服务运行时的文件根目录
hot: true, //开启热更新
hotOnly: true
}
}
//3.在npm运行`npx webpack-dev-server`就可以进行自动打包编译
//npm 从5.2版开始,增加了npx命令,使用已安装本地的工具,而不需要在package.json配置 scripts
复制代码
- 在index.js中
//如果模块启用了HMR,就可以用 module.hot.accept(),监听模块的更新。
if (module.hot) {
module.hot.accept('./library.js', function() {
// 使用更新过的 library 模块执行某些操作...
})
}
复制代码
2.4 babel: 将ES6/7/8 转 ES5代码
2.4.1 主要处理业务代码
- 安装
npm i babel-loader @babel/core -D
npm i @babel/preset-env -D
ES6/7/8语法转换为ES5语法,但是对新api并不会转换,可以通过 core-js@3进行转换
npm install core-js@3
复制代码
- 在webpack.config.js文件中
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
"@babel/preset-env",
{
useBuiltIns: "usage" //按需添加core-js@3,把用到的代码都转成低版本浏览器兼容的
corejs: 3,
}
]
]
}
}
]
}
复制代码
- index.js文件中
import "core-js/stable"
import "regenerator-runtime/runtime"
复制代码
2.4.2 开发类库,第三方模块或组件库,使用transform-runtime能避免声明的变量变成全局变量,且会污染全局环境
- 安装
cnpm i @babel/plugin-transform-runtime @babel/runtime -D
cnpm i @babel/runtime-corejs3 -D
复制代码
- 在webpack.config.js文件中
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": 3,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
}
复制代码