webpack 开发环境的基本配置
构建工具基于node.js环境运行,模块化采用 commonjs
一个基本的配置
创建配置文件 -- webpack.config.js
// webpack.config.js
// 用来处理路径
const path = require('path');
// webpack配置
module.exports = {
// 入口文件
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'bundle.js',
// 输出路径 __dirname node.js变量,当前文件的目录绝对路径
path: path.resolve(__dirname, 'dist'),
},
// loader配置
module: {
rules: [],
},
// 插件配置
plugins: [],
// 模式
mode: 'development',
// mode: 'production',
};
webpack-dev-server 自动打包编译
使用 webpack-dev-server 工具实现代码自动打包编译,修改和保存任意源文件,web服务器就会自动重新加载编译后的代码。
安装
npm install --save-dev webpack-dev-server
- 运行 npm install --save-dev webpack-dev-server 将该工具安装到项目的本地开发依赖。该工具依赖于webpack,在本地项目中必须安装webpack。
-
在命令行直接运行 webpack-dev-server 命令进行打包,报错,因为 webpack-dev-server 是本地安装的,无法把它当作脚本命令。需要借助于package.json文件中的指令运行 webpack-dev-server 命令。在 scripts 节点下新增
"dev": "webpack-dev-server"指令,运行npm run dev。或者新增
"start": "webpack-dev-server --open --port 3000 --concentBase dist --hot",运行npm run dev打开服务器。
-
命令参数
方式一:修改package.json的script节点
--open 自动在浏览器中打开该端口地址,后面可跟浏览器名称,如
firefox--port 修改运行时的端口号 ----host 修改运行时的域名,如127.0.0.1--contentBase 设置托管的根目录,在浏览器中直接打开该路径下的.html文件--hot 启动浏览器热更新,不会重新生成 bundle.js,只会生成一个
.js和.json补丁保存局部更新的代码,并实现浏览器的无重载异步刷新(对css等有效果,对js无效果)
方式二:修改config.js文件,新增devServer节点
/* webpack.config.js */
const path=require('path')
const webpack=require('webpack') // 启用热更新使用
module.exports={
// 入口文件
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'bundle.js',
// 输出路径 __dirname node.js变量,当前文件的目录绝对路径
path: path.resolve(__dirname, 'dist'),
},
devServer:{
open:true,
port:3000,
contentBase:'./dist',
hot:true
},
// 插件配置
plugins:[
// 放置热更新的模块对象
new webpack.HotModuleReplacementPlugin()
]
}
- webpack-dev-server 打包生成的 bundle.js 文件,在项目根目录
<script src="/bundle.js"></script>。并没有存放到实际的物理磁盘上,而是直接托管到电脑的内存中,在根目录找不到。由于需要实时打包编译,放在内存中速度会非常快。
html-webpack-plugin自动添加js入口文件
html-webpack-plugin,自动根据指定页面在内存中生成一个新页面之后,所有的打包好的 bundle 会自动添加到新页面的 body 底部。不再需要指定启动目录和手动处理 bundle.js 的引用路径。
安装
npm install --save-dev html-webpack-plugin
配置webpack.config.js
/* webpack.config.js */
// const path=require('path')
const htmlWebpackPlugin=require('html-webpack-plugin')
module.exports={
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 入口文件
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'bundle.js',
// 输出路径 __dirname node.js变量,当前文件的目录绝对路径
path: path.resolve(__dirname, 'dist'),
},
// 配置插件的节点
plugins:[
new htmlWebpackPlugin({
// 我们原来的index.html,作为模板
template:path.join(__dirname,'./dist/index.html'),
// dist目录下生成的文件名
filename:'index.html',
//生成的页面标题<head><title>Output Management</title></head>
title:'Output Management'
})
]
}
Loader(处理非js文件,翻译工作)
打包样式资源
安装依赖
npm i css-loader style-loader less-loader less -D
项目结构
$ tree -I "node_modules"
.
├── dist
│ ├── bundle.js
│ └── index.html
├── package.json
├── src
│ ├── index.css
│ ├── index.less
│ └── index.js
└── webpack.config.js
src/index.js
// 引入样式资源
import './index.css';
src/index.css
html,
body {
padding: 0;
margin: 0;
height: 100%;
background-color: pink;
}
配置webpack.config.js
// 用来处理路径
// const path = require('path');
const { resolve } =require('path');
// webpack配置
module.exports = {
// 入口文件
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'bundle.js',
// 输出路径 __dirname node.js变量,代表当前文件的目录绝对路径
// path: path.resolve(__dirname, 'dist'),
path: resolve(__dirname, 'dist'),
},
// loader 的配置
module: {
rules: [
//详细loader配置
//不同文件必须配置不同loader处理
{
// 正则匹配文件名
// 匹配哪些文件
test: /.css$/,
// 使用哪些loader进行处理
use: [
// use数组中loader执行顺序:从右到左,从下到上依次执行
// 将js中的样式资源插入进行,添加到head中生效
'style-loader',
// 加载css文件,变成commonjs模块,里面内容是样式字符串
'css-loader',
],
},
{
test: /.less$/,
// 使用哪些loader进行处理
use: [
// use数组中loader执行顺序:从右到左,从下到上依次执行
// 将js中的样式资源插入进行,添加到head中生效
'style-loader',
// 加载css文件,变成commonjs模块,里面内容是样式字符串
'css-loader',
// 将 less 文件编译成 Css 文件
// 需要下载 less - loader 和 less
],
},
],
},
// 插件配置
plugins: [],
// 模式
mode: 'development',
// mode: 'production',
};
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="./bundle.js"></script>
</body>
</html>
执行打包命令
$ npx webpack
打开 index.html 文件,可以看到 css 样式已经生效(右键->检查元素)
js动态生成了style标签
<html lang="en"><head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>html,
body {
padding: 0;
margin: 0;
height: 100%;
background-color: pink;
}
</style></head>
<body>
<script src="./bundle.js"></script>
</body></html>
打包样式资源-less文件
安装依赖
$ cnpm i less less-loader -D
src/index.js
// 引入less样式资源
import './index.less';
src/index.less
html,
body {
padding: 0;
margin: 0;
height: 100%;
background-color: pink;
}
新增配置 webpack.config.js
// webpack.config.js
// 用来处理路径
const path = require('path');
// webpack配置
module.exports = {
// 入口文件
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'bundle.js',
// 输出路径 __dirname node.js变量,当前文件的目录绝对路径
path: path.resolve(__dirname, 'dist'),
},
// loader配置
module: {
rules: [
// 处理less文件
{
test: /.less$/,
use: [
'style-loader',
'css-loader',
// 将less编译成css
'less-loader',
],
},
],
},
// 插件配置
plugins: [],
// 模式
mode: 'development',
// mode: 'production',
};
执行打包命令
$ npx webpack
打包Html资源
安装依赖
命令:
cnpm i html-webpack-plugin -D
npm install --save -dev html-webpack-plugin
创建一个空的HTML文件,自动引入打包输出的所有资源(js/css)
- 默认输出的HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack App</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script defer src="bundle.js"></script></head>
<body>
</body>
</html>
- src/index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack</title>
</head>
<body>
</body>
</html>
配置 Webpack.config.js
// webpack.config.js
// const path = require('path');
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// webpack配置
module.exports = {
// 入口文件
entry: './src/index.js',
// 输出
output: {
filename: 'bundle.js',
// path: path.resolve(__dirname, 'dist'),
path: resolve(__dirname, 'dist'),
},
// loader配置
module: {},
// 插件配置
plugins:[ // 配置插件的节点
/*
html-webpack-plugin
功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
需求:需要有结构的HTML文件
*/
new htmlWebpackPlugin({
// 复制'./src/index.html'文件,并自动引入打包输出的所有资源(JS/CSS)
template: resolve (__dirname,'./dist/index.html'), // 指定模板页面
filename:'index.html', // 指定生成页面名称,浏览器默认打开index.html
title:'Output Management'
})
],
// 模式
mode: 'development',
// mode: 'production',
};
执行打包命令
npx webpack
打包后输出 Html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack</title>
<script defer src="bundle.js"></script>
</head>
<body>
</body>
</html>
打包图片资源
安装依赖
cnpm i html-loader -D
npm install --save -dev html-loader url-loader file-loader
项目结构
tree -I node_modules
.
├── package.json
├── src
│ ├── index.html
│ ├── index.js
│ ├── index.less
│ └── weibo.png
└── webpack.config.js
src/index.js
// 引入less样式资源
import './index.less';
// js引入图片资源
import weibo from './weibo.png';
console.log(weibo);
// http://127.0.0.1:5500/dist/images/7f1a8e356f.png
src/index.less
html,
body {
padding: 0;
margin: 0;
height: 100%;
// background-color: pink;
}
.box {
width: 100px;
height: 100px;
// css引入图片资源
background-image: url('./weibo.png');
// 替换为:background-image: url(/dist/images/7f1a8e356f.png);
background-size: 100% 100%;
background-repeat: no-repeat;
}
src/index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>Webpack</title>
</head>
<body>
<div class="box"></div>
<!-- html引入图片资源 -->
<img src="./weibo.png" alt="">
<!-- 替换为:<img src="images/7f1a8e356f.png" alt=""> -->
</body>
</html>
配置 WebPack.Config.js
webpack5默认会处理图片资源,webpack4需要单独配置
| webpack5 | webpack4 | 说明 |
|---|---|---|
| asset/resource | file-loader | 发送一个单独的文件并导出 URL |
| asset/inline | url-loader | 导出一个资源的 data URI |
| asset/source | raw-loader | 导出资源的源代码 |
| asset | url-loader | 在导出一个 data URI 和发送一个单独的文件之间自动选择。 |
webpack4 配置
// webpack配置
// const path = require('path');
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 入口文件
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'bundle.js',
// 输出路径 __dirname node.js变量,当前文件的目录绝对路径
path: resolve(__dirname, 'dist'),
},
// loader 配置
module: {
rules: [
{
test: /.less$/
// 要使用多个loader处理用use
use: ['style-loader', 'css-loader','less-loader']
},
// 问题:默认处理不了html中img图片
{
//处理图片资源
test: /.(png|svg|jpg|jpeg|gif)$/,
// 使用一个loader
//下载url-loaderfile-loader
loader: 'url-loader',
options: {
// 图片大小小于8kb,就会被base64编码
// 优点:减少请求数量,减轻服务器压力
// 缺点:js体积会更大, 文件请求速度更慢
limit: 8 * 1024,
// 问题:url-loader默认使用es6模块解析,而 html-loader引入图 片是commonjs
// 解析时会出现: [object Module]
// 解决:关闭url-loader的es6模块化,使用commonjs解析
esModule: false,
// 给图片进行重命名
// 自定义命名 取hash前10位
// [ext]取文件原来扩展名
name: '[hash:10].[ext]'
}
},
{
test: /.html$/i,
// 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
loader: 'html-loader',
},
]
},
// 插件配置
plugins: [
/*
html-webpack-plugin
功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
需求:需要有结构的HTML文件
*/
new htmlWebpackPlugin({
// 复制'./src/index.html'文件,并自动引入打包输出的所有资源(JS/CSS)
template: resolve (__dirname,'./dist/index.html'), // 指定模板页面
filename:'index.html', // 指定生成页面名称,浏览器默认打开index.html
title:'Output Management'
})
],
// 模式
mode: "development",
// mode: "production",
}
package.json
{
"devDependencies": {
"css-loader": "^6.7.1",
"html-loader": "^3.1.0",
"html-webpack-plugin": "^5.5.0",
"less": "^4.1.2",
"less-loader": "^11.0.0",
"style-loader": "^3.3.1",
"webpack": "^5.72.1",
"webpack-cli": "^4.9.2"
}
}
webpack5配置
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// webpack配置
module.exports = {
// 入口文件
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'bundle.js',
// 输出路径 __dirname node.js变量,当前文件的目录绝对路径
path: path.resolve(__dirname, 'dist'),
// 自定义资源文件名
assetModuleFilename: 'images/[hash:10][ext][query]',
},
// loader配置
module: {
rules: [
// 处理less文件
{
test: /.less$/i,
use: ['style-loader', 'css-loader', 'less-loader'],
},
// 处理资源文件
{
test: /.(png|svg|jpg|jpeg|gif)$/i,
// 默认: 小于 8kb 的文件,将会视为 inline 模块类型,否则会被视为 resource 模块类型。
type: 'asset',
},
// 处理html中的图片
{
test: /.html$/i,
loader: 'html-loader',
},
],
},
// 插件配置
plugins: [
// 复制一份HTML文件,并自动引入打包资源(js/css)
new HtmlWebpackPlugin({
template: './src/index.html',
}),
],
// 模式
mode: 'development',
// mode: 'production',
};
打包字体资源
可以从 iconfont(www.iconfont.cn/)网站下载字体文件
安装依赖
npm install --save-dev file-loader
npm install webpack webpack-cli --save-dev
打包后的项目结构
$ tree -I node_modules
.
├── dist
│ ├── bundle.js
│ ├── images
│ │ ├── 5b0edd384b.ttf
│ │ ├── 969b5fedf8.woff
│ │ └── d79bd05095.woff2
│ └── index.html
├── package.json
├── src
│ ├── iconfont
│ │ ├── iconfont.css
│ │ ├── iconfont.js
│ │ ├── iconfont.json
│ │ ├── iconfont.ttf
│ │ ├── iconfont.woff
│ │ └── iconfont.woff2
│ ├── index.html
│ ├── index.js
└── webpack.config.js
src/index.js
// 引入css样式资源
import './iconfont/iconfont.css';
src/index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>Webpack</title>
</head>
<body>
<span class="iconfont icon-home"></span>
</body>
</html>
配置 webpack.config.js
webpack4
// webpack.config.js
// const path = require('path')
const { resolve } = require('path')
const HtmlWebpackPlugin = require ('html-webpack-plugin')
module.exports ={
// 入口文件
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'bundle.js',
// 输出路径 __dirname node.js变量,当前文件的目录绝对路径
// path: path.resolve(__dirname, 'dist'),
path: resolve(__dirname, 'dist'),
// 自定义资源文件名
assetModuleFilename: 'images/[hash:10][ext][query]',
},
// Loader 配置
module: {
rules: [
{
test: /.css$/,
use: ['style-loader', 'css-loader']
},
// 打包其他资源(除了js/html/css资源外的资源)
{
// 排除 Css/js/html 资源
exclude: /.(js|less|html)$/i,
loder: 'file-loader',
},
// 处理 字体 资源
{
test: /.(woff|woff2|eot|ttf|otf)$/,
use: ["file-loader"],
}
]
},
// 插件配置
plugins: [
new htmlWebpackPlugin({
// 指定模板页面
template:'./src/index.html',
// 指定生成页面名称,浏览器默认打开index.html
filename:'index.html',
title:'Output Management'
})
],
// 模式
mode: 'development',
// mode: 'production',
]
}
webpack5
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// webpack配置
module.exports = {
// 入口文件
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'bundle.js',
// 输出路径 __dirname node.js变量,当前文件的目录绝对路径
path: path.resolve(__dirname, 'dist'),
// 自定义资源文件名
assetModuleFilename: 'images/[hash:10][ext][query]',
},
// loader配置
module: {
rules: [
// 处理css文件
{
test: /.css$/i,
use: ['style-loader', 'css-loader'],
},
// 处理less文件
{
test: /.less$/i,
use: ['style-loader', 'css-loader', 'less-loader'],
},
// 处理资源文件
{
test: /.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset',
},
// 处理html文件,加载其中的图片
{
test: /.html$/i,
loader: 'html-loader',
},
// 处理字体文件
{
test: /.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
},
],
},
// 插件配置
plugins: [
// 复制一份HTML文件,并自动引入打包资源(js/css)
new HtmlWebpackPlugin({
template: './src/index.html',
}),
],
// 模式
mode: 'development',
// mode: 'production',
};
devServer
开发服务器,自动化开发(自动编译,自动打开浏览器,自动刷新浏览器)
特点:
| 只会在内存中编译打包,不会有任何输出 |
|---|
安装依赖
npm install webpack-dev-server --save-dev
配置 Webpack.config.js
webpack4配置
const {resolve} = require('path');
constHtmlWebpackPlugin=require('html-webpack-plugin');
module.exports = {
// 特点: // 只会在内存中编译打包,不会有任何输出
// 开发服务器配置
devServer: {
// 项目构建后路径
contentBase: resolve(__dirname, 'dist'),
// 启动gzip压缩
compress: true,
// 端口号
port: 3000,
// 自动打开浏览器
open: true
}
}
webpack5配置
module.exports = {{
// 开发服务器配置
devServer: {
// 从目录提供静态文件
static: {
directory: path.join(__dirname, "public"),
publicPath: "/",
},
// 启动后打开浏览器
open: true,
// 监听请求的端口号
port: 8080,
},
}
配置启动命令
为了方便启动,可以配置启动命令
package.json
{
"scripts": {
"dev": "webpack serve",
"build": "webpack"
},
}
启动开发服务器
npm run dev
webpack.config.js 完整配置
webpack4配置
// 绝对路径引入方法
const { resolve } = require('path')
// 引入 处理 HTML 的插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// 文件入口
entry:'./src/index.js',
// 文件输出
output: {
filename:'built.js',
path: resolve(_dirname, 'build'),
// 自定义资源文件名
assetModuleFilename: "images/[hash:10][ext][query]",
},
// 开发服务器配置
// 特点: // 只会在内存中编译打包,不会有任何输出
devServer: {
// 项目构建后路径
contentBase: resolve(__dirname, 'dist'),
// 启动gzip压缩
compress: true,
// 端口号
port: 3000,
// 自动打开浏览器
open: true
}
// loader配置
module:{
rules:[
{
// 处理 Less 资源
test:/.less$/,
use: [
'style-loder','css-loader','less-loader'
]
},
{
// 处理 Css 资源
test:/.css$/,
// 写法一:
// use: ['style-loader', 'css-loader']
// 写法二:
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' }
]
},
{
// 处理 Sass 资源
test: /.s[ac]ss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
]
},
{
//处理图片资源
test: /.(jap|png|gif)$/,
/**
* url-loader:
* 1)处理css中的图片资源,注意:不能处理html中的img 标签
* 2)url-loader基于file-loader运行,所以需下载 url-loader和file-loader
* 3)options:loader的其他配置
* limit: 图片大小小于8Kb,就会被处理成base64;
* esModule:url-loader默认使用es6解析。设置为 false:关闭它的es6模块化,使用commonjs解析;
* name: 给图片进行重命名。[hash:10] - 取图片的 hash的前10位;[ext] - 取文件原来的拓展名。
*/
loder: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
// html-loader 和 url-loader 同时使用会冲突
// 解决: 关闭 ES6 模块化, 开启 Common JS
esModule: false,
// 打包后 存放文件的文件夹
outputPath: 'images'
}
},
{
//处理html中 img 资源
/**
* html-loader: 处理html文件的img图片(负责引入img,从而 能被url-loader进行处理)
*/
test: /.html$/,
loder: 'html-loader',
},
{
// 处理其他资源
exclude: /.(html|js|css|less|jpg|png|gif)/,
loder: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath:'media'
}
}
]
},
// plugins 的配置
plugins: [
//处理 html 的资源
// 复制一份HTML文件,并自动引入打包资源(js/css)
/**
* html-webpack-plugin
* 1) 不传参的情况 - new HTMLWebpackPlugin():会在配置的 output文件夹创建一个空的html, 自动引入打包输出的所有资 源,包括js, css...
* 2) 参数template:复制设置的'./src/index.html'文件到配置的 output文件夹,并自动引入打包输出的所有资源
*/
new HtmlWebpackPlugin ({
template: './src/index.html'
})
],
// 模式
mode: "development",
// mode: 'production',
}