赞
踩
1)采用模块化开发,但是不同的浏览器对于模块化的支持不一样,模块化本身又存在多种规范
2)使用新特性例如es+或者ts来编写代码,提高效率保证安全性,也会用sass,less来编写css,浏览器在默认情况下也不能处理
3)实时监听开发过程,使用热更新
4)项目编码完成后,在部署之前需要对代码进行压缩处理
为了解决这些问题,使得开发者可以随意使用想用的技术栈进行项目开发,最终结果可以在浏览器直接展示,因此就会用到打包工具,我们项目使用的react,vue,angular等框架本身就集成了webpack,所以看似没配置,但是其实功能你已经在用了。
是为现代js应用提供静态模块打包的工具
可以将不同类型资源按模块处理进行打包
打包后最终产出静态资源,最终产出的内容可以直接部署在静态服务器上使用
webpack支持不同规范的模块化开发,例如esmodule,commonjs,amd规范等
utils.js
const sum = (m, n) => {
return m+n;
}
const square = (m) => {
return m*m;
}
export {sum, square};
index.js
import {sum, square} from './js/utils.js';
console.log(sum(1,2));
console.log(square(3));
index.html手动导入Js文件
<body>
<script src="./src/index.js"></script>
</body>
打开浏览器发现报错了,这里使用的是esmodule规范
解决办法:
index.html手动导入Js文件
<body>
<script src="./src/index.js" type="module"></script>
</body>
但是这不能解决根本问题,比如:
api.js commonjs规范
const getInfo = () => {
return {
name: 'lql',
age: 20
}
}
module.exports = getInfo;
index.js
const getInfo = require('./js/getInfo.js');
console.log(getInfo());
这时候我们就需要有个能帮我们把这些规范都统一一下的东西,那就是webpack
终端执行npx webpack,会产生一个dist目录,这是因为webpack会默认找到./src/index.js作为入口,
修改index.html中的代码
<body>
<script src="./dist/main.js"></script>
</body>
回到浏览器就不报错了
将index.js重命名main.js,再次执行npx webpack会报错,所以就需要用到一些配置
npx webpack --entry ./src/main.js终端执行这个命令就不会报错啦
npx webpack --entry ./src/main.js --output-path ./build终端执行这个命令修改输出目录
终端命令比较麻烦,所以可以通过一下方式:
终端执行npm run build即可
module.exports = {
entry: './src/index.js',
output: {
filename: 'build.js',
path: './dist/main.js' // 这个有问题,会报错
}
}
修改package.json文件中的build值为webpack即可
这时候执行npm run build会报错
原因是:
Webpack的错误信息指出了配置对象中的一个问题,具体是关于 output.path
的。这个错误告诉我们提供的值 ./dist/main.js
不是一个绝对路径。
在Webpack中,output.path
是用来指定输出文件的目录的,而且必须是一个绝对路径。绝对路径是从文件系统的根目录开始的完整路径,例如 /user/project/dist
。
解决这个问题的方法是确保 output.path
的值是一个绝对路径。你可以通过两种方式来实现:
使用绝对路径: 直接指定输出目录的绝对路径,例如 /user/project/dist
。
使用Node.js内置的路径解析模块: 在Webpack配置文件中使用Node.js内置的path
模块来生成绝对路径。例如:
const path = require('path');
module.exports = {
// 其他配置...
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
// 其他配置...
};
path.resolve(__dirname, 'dist')
将会生成当前Webpack配置文件所在目录下的 dist
目录的绝对路径。
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'build.js',
// path: './dist/main.js'
path: path.resolve(__dirname, 'dist')
}
}
这样的话npm run build就没问题啦
不是所有的文件都能被打包,就需要loader来进行文件的转换。默认只能打包js文件。
css-loader只是能让webpack可以识别我们的css语法,并不能在元素上生效对应的css样式,需要安装style-loader
npm i css-loader
使用有两种方式:
1)行内
2)配置文件
npm i style-loader安装好style-loader后,
执行npm run build会报错
这个问题跟loader的执行顺序有关系,代码现在写的他会先style-loader进行处理,然后结果被传递给css-loader,之后css-loader处理后把结果重新交给compare对象进行打包操作,执行顺序默认从右到左,所以说修改下顺序就可以解决问题了
这时候你在执行npm run build 就没有报错啦,而且页面上样式已经生效了
作用就是在界面中生成一个style标签
新建login.less文件
安装npm i less -D
less编译为css?
npx less ./src/css/login.less loginLessToCss.css终端执行命令后,会生成一个loginLessToCss.css文件,就是Less文件所编译成的css文件
但是不可能说我有好多个less文件,都这样执行命令,所以安装less-loader
node-modules里有一个包browserlist,配置需要兼容的平台
终端执行npx browserslist命令可以得到符合条件的平台
也可以新建.browserslistrc文件
用JavaScript工具和插件转换CSS的工具。它的主要功能是将CSS代码转换为抽象语法树(AST),然后通过插件对AST进行操作和转换,最后再将AST转换回CSS代码。PostCSS的灵活性使得开发者可以编写自定义的插件来处理各种CSS相关的任务,比如自动添加浏览器前缀(autoprefixer插件)、支持新的CSS语法等。利用js转换样式的工具
安装postcss:npm i postcss,
要想直接通过行内或者终端的方式npx postcss是不允许的,需要再装一个包,npm i postcss-cli
新建css文件 一个网站autoprefixer.github.io
test.css文件
.example {
transition:all .5s;
uer-select:none;
background:linear-gradient(to bottom, white, black);
}
这三个样式不是所有的浏览器都能兼容,所以希望有这么一个工具帮我们自动添加前缀,实现兼容
安装postcss-cli,然后终端使用命令:npx postcss -o ret.css ./src/css/test.css
这时候发现没有用,并没有实现兼容,原因是postcss还需要一些插件的支持,现在想要一个加前缀的插件npm i autoprefixer
这时候终端执行npx postcss --use autoprefixer -o ret.css ./src/css/test.css根据browserlistrc文件内的条件进行兼容处理,这时候ret.css文件里就有兼容处理了
当css文件中有一些可能在不同浏览器是不能做到完全兼容的样式时,做一些特殊处理
这时候安装npm i postcss-loader
webpack配置文件中修改加了postcss-loader,打开浏览器页面发现没有加上前缀,是因为我们需要添加插件
当我们修改css文件中color:#12345678时,因为16进制常见的是6位,但这里是8位,在谷歌浏览器没有问题,但别的浏览器可能会有兼容问题
当我们使用babel的时候,会遇见postcss-preset-env,会说这是预设,是不同插件的集合
安装npm i postcss-preset-env
这样你再执行npm run build就会发现color: #12345678变成了color:rgba();的格式
简写
这样的代码有些冗余,可以单独放在一个配置文件中,方便通用性配置的管理
新建文件postcss.config.js
当我们有个css1文件,这个文件里没有需要兼容性处理的代码,而另一个文件css2里有需要做兼容性的代码,css1文件内通过@import './css2.css'的方式引入,发现并没有做兼容性处理,原因是因为先postcss-loader,然后css-loader才会处理@import 或者url()这种的css文件,他会自动的把他替换为require语法,但是css-loader并没有兼容处理的能力,所以导致这个问题,这时候就需要引入importLoaders
方式一:img标签设置src
新建Image.js文件,src下新建img文件夹,放点图片
在Index.js文件中
//开始file-loader的展示
import './js/Image.js';
执行npm run build,发现报错了
安装npm i file-loader -D,修改webpack配置
新增
{
test: /\.(png|svg|gif|jpe?g)$/,
use: ['file-loader']
}
再次执行npm run build,
src的值之所以是这样,是因为Image.js中我们用require('../img/smile.png')的原因
解决办法
1、
.default,这是因为file-loader升级后要适配webpack5的原因
2、不加.deault,而是修改webpack的配置,不让转化为esModule
3、不修改webpack配置,而是通过import的方式导入
方式二:css设置background:url
npm run build后发现页面没展示
原因是定位到的图片是
原因解释:在遇到css-loader处理css文件时,遇到url会替换成require语法,所以应该是要有个.default的,但是url在css文件里,又不支持.default的写法,所以只能修改webpack
再次执行npm run build,发现没问题了
执行npm run build后查看dist文件夹
安装npm i url-loader -D
执行npm run build,页面展示没问题,但是dist下边没目录了
file-loader:把我们当前的图片名称或者路径返回,及打包后的图片资源直接拷贝到dist目录下
url-loader:把我们要打包的图片资源以base64uri的方式加载到代码中
可以审查下元素
url-loader好处就是减少了请求的次数,但也有风险,如果图片资源较大,那这种方式就不好了
在url-loader内部可以调用file-loader
asset module type
1)asset/resource 相当于file-loader
2)asset/inline 相当于url-loader
3)asset/source 相当于raw-loader
4)asset 设置配置参数动态配置
这种设置执行npm run build会展示
如果想对打包后的结果进行一些配置,有两种方式
1)全局配置
npm run build后发现可以了
全局不方便
2)局部配置
新建font文件夹存放iconfont库
新建Font.js
index.js文件中引入
npm run build发现报错了,因为缺少可以处理iconfont的loader
配置loader
npm run build 没问题
loader:是对特定的模块类型做一个转换
插件:可以做更多的事情,可以用于执行范围更广的任务。包括:打包优化,压缩处理,资源管理,注入环境变量。
想要使用一个插件,你只需要 require()
它,然后把它添加到 plugins
数组中
安装npm i clean-webpack-plugin -D
npm run build就会自动清空dist文件夹了
dist文件夹下会自动生成静态html文件
新建public文件夹,下边新建index.html
webpack文件配置
npm run build后dist文件夹下的index.html
比如vue项目生成的public文件夹
给我们这个index.html替换下
npm run build会报错
原因是因为会把./原封不动拿过来给BASE_URL,但是我们期望的是个字符串,所以说加个""就可以了
为什么前端会用到babel?
比如我有个react项目,那我在项目中使用的JSX,TS,ES6+这些语法,默认浏览器是不能直接识别的。我们要转化为浏览器平台能直接使用的,就会用babel工具
安装npm i @babel/core -D
想在命令行使用,就安装@babel/cli
命令输入npx babel src --out-dir build 会生成一个build文件夹,但发现build文件夹内的内容跟之前es6的语法没有区别,这时候就还需要安装一个工具包npm i @babel/plugin-transform-arrow-functions -D
终端执行npx babel src --out-dir build --plugins=@babel/plugin-transform-arrow-functions
发现build文件夹内的Index.js就已经转换成普通函数了
还有const 转 var
npm i @babel/plugin-transform-block-scoping -D
npx babel src --out-dir build --plugins=@babel/plugin-transform-arrow-functions,@babel/plugin-transform-block-scoping
这多麻烦,那么多玩意儿要转呢,所以也需要想postcss-preset-env这样的一个预设集合的存在,一窝端
npm i @babel/preset-env -D
npx babel src --out-dir build --presets=@babel/preset-env
一个一个引入太麻烦,直接把预设放在这
那什么浏览器会被兼容这种转换的规则呢,就得说回.browserslistrc文件了,跟这里边的有关系
那还有一个可以配置的地方
target这个更优先
简洁方法,新建一个babel.config.js
是什么?当代码遇见promise,generator,symbol等时,@babel/preset-env不一定有用,所以要用polyfill打一个补丁
安装npm i core-js regenerator-runtime
三个值:
false默认,不对当前js做polyfill
usage,依据用户代码当中所使用的新语法进行polyfill
entry,依据浏览器平台进行polyfill
加上corejs: 3是因为不加报错了,需要指定下corejs的版本
可能node_modules里边有别的用到了polyfill的地方,那填充的就有冲突了,所以使用babel-loader时要配置下
npm i copy-webpack-plugin -D
用于在打包过程中对 JavaScript 代码进行压缩和混淆,以减小文件体积并提升加载性能
设置 parallel: true
时,它会启用并行压缩,即使用多个进程来加速代码压缩过程。这在大型项目中特别有用,可以显著减少压缩时间。
插件:webpack-bundle-analyzer
是一个用于可视化分析 Webpack 输出文件体积的工具。它可以帮助你了解各个模块在打包后的体积情况,从而优化你的打包配置和代码结构,减小文件体积,提升网页加载速度。
是一个webpack提供的开发服务器工具,用于在开发过程中快速启动一个本地服务器并实时监视文件变化,自动重新编译和刷新页面。它能够提供实时的代码变化反馈,同时支持热模块替换(HMR),使开发者能够更高效地进行前端开发。
打包完成后想要修改代码后同步实现页面的更新,两种方式:
1)
2)
但是这种效率不是最优的,现在的模式是watch+vscode的插件live server实现的,相对于webpack-dev-server有些不足:
1.所有的原代码都会重新编译
2.每次编译成功之后都需要进行文件读写,都要进行磁盘交互
3.webpack本身具有live server的实现
4.组件化开发时,如果只是部分组件更新,会导致全部更新,但webpack有热更新实现局部更新
安装npm i webpack-dev-server
终端执行npm run serve,默认起了一个服务,端口是8080,并没有产生dist文件夹,是因为放在内存了,而不是磁盘的读写
安装npm i express webpack-dev-middleware
新建server.js文件
这时候通过localhost:3000也可以访问页面啦
浏览器只需要对局部发生变化的数据进行展示即可,
在开发阶段应该把.browserslistrc内容给屏蔽掉,再加上热更新功能
默认还是刷新整个页面进行工作的,但是我们不期望这样,所以应该在入口文件中把想要进行热更新的文件给他写上
安装npm i @babel/preset-react react react-dom
新建page文件夹,新建App.jsx文件
但是更新image.js有热更新,而修改App.jsx文件的值就没有热更新,而是重新刷新了页面
npm i @pmmmwh/react-refresh-webpack-plugin react-refresh -D --force
这时候执行npm run serve发现都实现了热更新
安装 npm i vue@2.6.14 vue-template-compiler@2.6.14 -D
新建App.vue文件
vue-loader15版本之前可以直接处理,之后需要自己加个插件
output:{
path:告知webpack把资源产出到哪个目录下
publicPath:''(默认''没有的话浏览器会帮我们加/)告知index.html假如内部引用了什么资源,你应该怎么找到引用路径(域名+publicPath+filename)
如果是'/'比较奇怪:
npm run serve发现没问题
但是如果通过dist下的index.html然后open deault browser会发现找不到js资源,原因是因为最好还是写成publicPath:'./',但是./这种方式通过npm run serve发现又不行了
}
比如说npm run serve后,http://localhost:8080/js/login.js
注意:如果我们开发阶段用webpack-dev-serve去开启一个本地服务的操作对资源进行访问,那么我们更加关注的是publicPath,所以空字符串或者'/'都可以,但是'/'npm run build就会有问题
得一样
publicPath这里是/lg,那不可能通过http://local:8080来访问到,得再加个/lg
contentBase有这样一个使用场景,在public文件夹下有一个工具js文件,这个文件我不希望被webpack打包,只是帮我拷贝一下就行,但是打包后的index.html又引用到了这个工具文件,这时候就得通过contentBase来找path.resolve(__dirname, 'public')绝对路径,因为这个工具文件在public下,跟contentBase配套的一个配置,用于监控资源是否更新,watchContentBase: true
hotOnly的存在原因:当页面中存在很多组件,当一个组件可能出现一些语法错误时,当我们发现问题并且修改后,发现会因为这一个组件导致整个页面进行了刷新,这样不好,所以出现了hotOnly:true
port:4000重启一个端口
open:true会自动打开页面
compress:true压缩,性能提升
historyApiFallback: true的使用场景,页面通过路由实现页面跳转,当从home跳转到about,再刷新about页面会找不到,这时候加上这个配置就可以了
4000端口的服务去请求服务端的接口,然后把数据给前端
分为三种情况:
绝对路径
相对路径:根据路径,路径确定了,往后就看他是文件夹还是文件,文件就看有没有明确后缀,如果没有,就是extensions里的.js,.json,如果是文件夹,默认会给他补全,index
模块:找node_modules下的模块就行
webpack配置
import
或 require
的别名,来确保模块引入变得更简单mode的值默认是production,npm run build后会比较优化,
如果改为mode: 'development',打包后会更加便于阅读,打包后的文件里会有个eval()的包裹,原因是因为当设置为development模式后,相当于加了个devtool:'eval'
devtool:控制是否生成,以及如何生成 source map
当我开发过程中如果语法有一些错误,执行npm run serve后会看到控制台报错,但是报错的定位是打包后的js文件,我们无法快速定位到问题出在哪里,这时候就需要source-map了,是个映射技术,可以依据转换之后的代码,返还成原代码
便于调试,打包后会多一个.js.map
值:
eval
souce-map
eval-souce-map
inline-source-map 少一次请求,不会生成.js.map文件
cheap-source-map 定位错误只会有行信息,没有列信息,而且会优化,比如说代码空的行会被删除等
cheap-module-source-map 原本的代码定位
hidden-source-map 有.js.map文件 文件内也没有sourceMappingURL信息,定位错误时文件名是打包后的文件名了,定位不到源代码文件
nosources-souce-map 有.js.map文件 只有错误提示,没有源代码定位文件
vue框架使用的是source-map
react框架使用的是cheap-module-source-map
全局安装npm i ts,会生成ts compiler解析器
终端执行tsc --init,当前目录下会生成tsconfig.json文件
安装npm i ts-loader
用到一个预设
npm i @babel/preset-typescript
babel-loader在代码打包npm run build时如果有语法错误不会报错,但是在运行阶段会报错
ts-loader在代码打包npm run build时如果有语法错误会报错
解决办法?
使用babel-loader
在package.json文件内新增
这样就会在打包之后进行ts检查
webpack-merge
项目代码:
const projectName = process.env.ENV_PROJECT || process.argv[2]; // 项目名称
process.argv
webpack.base.config.js
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。