webpack5 入门学习笔记(二)开发环境配置
写在前面
本来想着只是两个小节,学完就总结,结果没想到中间会遇到这么多的坑。
webpack开发环境的基本配置
webpack打包其他资源
定义
- 不需要做任何处理,只要原封不动的输出,不用优化压缩的统称为其他资源
方法
- 选择阿里矢量图标库
- 选择图标,加入购物车下载代码,如果如法响应可先添加至项目进行下载
- 下载下来的包括字体图标的配置,点击其中的
HTML
文件可以查看字体图标的用法,这里使用font-class
方法引用
- font-class 引用 font-class 是 Unicode 使用方式的一种变种
- 主要是解决 Unicode书写不直观,语意不明确的问题。
- 与 Unicode 使用方式相比,具有如下特点:
- 相比于 Unicode 语意明确,书写更直观。
- 可以很容易分辨这个 icon 是什么。
- 因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class里面的 Unicode 引用。
-
使用步骤如下:
第一步:引入项目下面生成的fontclass
代码:<link rel="stylesheet" href="./iconfont.css">
第二步:挑选相应图标并获取类名,应用于页面:
<span class="iconfont icon-xxx"></span>
图标相应类名就在这个文档上方,
iconfont.css
文件中也可以查看在
index.html
文件中编写好了之后,在index.js
文件中引入iconfont.css
文件(这样就不用在index.html
界面引入了)import './iconfont.css'
-
查看
iconfont.css
文件,看到还需要对应的ttf、woff、woff2
等文件,根据实际情况从下载的图标代码中复制到项目中 -
接下来编写
webpack.config.js
文件基本的配置
要点记录
-
{resolve}
拼接绝对路径的方法,两种引入方式均可const { resolve } = require('path') path:resolve(__dirname,'dist') ------------- const path = require('path'); path:path.resolve(__dirname,'dist')
-
'file-loader'
打包其他资源 下载file-loader
可以用排除法,排除其他被处理过的资源//排除css/js/html资源 exclude: /\.(css|js|html)$/
-
使用低版本的
loader
可能会报错ReferenceError: module is not defined
(1) 将版本升级
(2) 使用
type: 'asset/resource'
,代替file-loader
也可以
在每一个type
值后面配置geneator
属性,生成的意识,里面是个对象,配置下filename
,效果等于使用file-loader
配置options
中的name
属性 -
webpack5
可以使用 资源模块类型(asset module type
),替代file-loader
等。资源模块类型通过添加四种新的模块类型,来代替
Loader
(1)
asset/resource
发送一个单独的文件并导出URL
,替代file-loader
(2)
asset/inline
导出一个资源的data URL
,替代url-loader
(3)
asset/source
到处资源的源代码,之前通过使用raw-loader
实现。(4)
asset
在导出一个data URL
和发送一个单独的文件之间做选择,之前通过url-loader+limit
属性实现参照:
反面教材:
在浏览器中打开打包之后的index.html
还是无法显示字体图标
控制台报错:Failed to load resource: net::ERR_FILE_NOT_FOUND iconfont.css
然后更改src
下index.html
中link
引用的路径,找到一种把css单独打包
不打包进js
文件中,然后打包后的js
文件放在body
中就能在index.js
中用append
方法添加,最后显示出来
参考:webpack成长指北第9章—webpack如何对icon字体进行打包
后来找到了错误,在引用的时候classname
书写错误,每个图标对应的名称在css
文件中可以查看,复制的时候少了一段,但是测试的时候一直没有更改html
中引用的,所以即便控制台中不报错了还是没出来结果
事实告诉人们,除了实践出真知之外还需要知道注重细节必不可少,否则就只是想是想不到是什么离谱的问题的
代码实现
const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
//入口文件
entry: './src/index.js',
//出口
output: {
//输出的文件名
filename: 'bundle.js',
//输出的路径
path: resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
//打包其他资源(除了html/js/css/less资源以外的资源)
{
//排除css/js/html资源
exclude: /\.(css|js|html)$/,
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]'
},
// type: 'asset/resource',
// generator: {
// filename: 'assets/[name].[hash:6].[ext]'
// }
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
webpack devServer
定义
- 开发服务器
devServer
用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
特点
- 只会在内存中编译打包,不会有任何输出(如果要输出,使用
webpack
命令)
使用方法
- 安装命令
npm i webpack-dev-server -D
- 启动指令
也可以在npx webpack serve //webpack5 使用此命令
package.json
中设置运行命令 - 基本配置
devServer: { //运行代码的目录 contentBase: resolve(__dirname, 'dist'), //启动gzip压缩 compress: true, //端口号 port: 3000, //首次运行自动打开浏览器,true代表默认浏览器 open:'Chrome' }
要点记录
-
如果不起作用可以尝试设置
devServer
的publicPath
属性webpack-dev-server实际上并没有在项目树中创建任何文件,而是将它们直接加载到内存中。接下来,我们devServer在开发模式下使用它,并设置它的contentBase属性,该属性告诉服务器从何处提供内容。但是默认情况下,打包的文件将在浏览器中可用,默认情况下publicPath该文件在浏览器中可用/。如果要自行分配的目录,我们要告诉webpack更改其默认值,并设置devServer的publicPath属性。
publicPath:’/’ //也可以自己设置 -
如果无法自动刷新 设置
target:'web'
参照:webpack5.0 使用webpack-dev-server时,无法自动刷新页面 -
个人的情况是
output
中配置了publicPath:'./'
就没有办法自动刷新,注释掉,重新启动devserver
就可以自动刷新了
代码实现
const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
//入口文件
entry:'./src/index.js',
//出口
output: {
//输出的文件名
filename: '[name].bundle.js',
//输出的路径
path: resolve(__dirname, 'dist'),
//publicPath: "/",
clean:true //清理之前打包输出的旧文件
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
//打包其他资源(除了html/js/css/less资源以外的资源)
{
//排除css/js/html资源
exclude: /\.(css|js|html|less)$/,
loader: 'file-loader',
options: {
name: '[name].[hash:10].[ext]',
}
// type: 'asset/resource',
// generator: {
// filename: 'assets/[name].[hash:6].[ext]'
// }
}
]
},
devtool: 'inline-source-map',//错误追踪
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
//inject: 'head',
scriptLoading: 'blocking',
title:'Hot Module Replacement'
}),
],
mode: 'development',
target: 'web',
//开发服务器 devServer 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
//特点:只会在内存中编译打包,不会有任何输出
//启动devServer指令为:npx webpack-dev-server
devServer: {
contentBase: './dist',
//启动gzip压缩
compress: true,
//端口号
port: 3000,
//首次运行自动打开浏览器
open:'Chrome'
}
};
webpack 开发环境配置
-
index.html
<!DOCTYPE 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>开发环境配置</title> </head> <body> <h1>开发环境配置</h1> <div style="color: rgb(15, 233, 99);">这是webpack学习</div> <span class="iconfont icon-icon-test"></span> <div id="box"> <img src="./react.jpg" alt="react"> </div> </body> </html>
-
index.less
#box { width: 300px; height: 300px; background-image: url("./react.jpg"); background-repeat: no-repeat; background-size: 100% 100%; } img { /*只允许缩小不允许放大,依赖于父级容器的尺寸*/ max-height: 100%; max-width: 100%; }
-
index.js 入口文件
import "./fonts/iconfont.css"; import "./index.less" function add(x,y) { return x + y; } console.log(add(56, 44)); console.log(add(10, 20));
-
webpack.config.js
要点记录
- 报错
Error: Cannot find module 'less'
。
安装less
解决npm install less --save-dev
- 配置输出路径
入口文件 在output
的filename
处配置
其他的在options
中的outputPath
处配置
在使用use
的同时不能配置options
样式文件是和js
一起的不用再指定目录了
html-loader
无需配置,自动打包到url-loader
处理的图片资源文件夹
代码实现
/**
* 开发环境配置:能让代码运行起来
*/
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: "./src/index.js",
output: {
filename: 'js/bundle.js',
path: resolve(__dirname, 'dist'),
clean:true //清理旧文件
},
target:'web', //解决devserver不能自动刷新
module: {
rules: [
//loader配置
{
//处理less资源
test: /\.less$/,
use:[
'style-loader',
'css-loader',
'less-loader'
]
},
{
//处理css资源
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
//处理图片资源(样式中的图片资源,html中的是处理不了的)
test: /\.(jpg|png|gif)$/,
loader: 'url-loader', //通过es6module解析
options: {
limit: 8 * 1024,
name: '[name].[hash:10].[ext]',
//关闭es6模块化,开启commonjs模块化
esModule: false,
outputPath:'img'
}
},
{
//处理html中的img资源
test: /\.html$/,
loader: 'html-loader',
options: {
esModule: false //webpack5中这里也需要设置
}
},
{
//处理其他资源
exclude: /\.(html|js|css|less|jpg|png|gif)$/,
loader: 'file-loader', //url-loader是基于file-loader封装的,多一些压缩功能,比如讲图片转成base64格式
options: {
name: '[name].[hash:10].[ext]',
outputPath:'media'
}
}
]
},
plugins: [
//plugins配置
new HtmlWebpackPlugin({
template: "./src/index.html",
scriptLoading: 'blocking'
})
],
devServer: {
//自动打包编译
contentBase: resolve(__dirname, 'dist'),
//g压缩
compress: true,
//端口号
port: 8080,
//第一次运行自动打开浏览器,true默认,'Chrome'谷歌
open:'Chrome'
},
mode:'development'
}
写在后面
学习这两小节遇到了太多因为是新版本才出现的问题了,也看到一些降版本就能解决问题的方法,但是既然出了新版本,那就用新版本不断解决问题,总不能遇到问题就降版本,总有降无可降的时候。
人还是得往前看,过去的已经永远消失在时间长河之中了,过往的人和事早就湮没在岁月中了,记忆也不能保真,只能向前,无可回头。