webpack

1、现代web开发的问题:

1)采用模块化开发,但是不同的浏览器对于模块化的支持不一样,模块化本身又存在多种规范

2)使用新特性例如es+或者ts来编写代码,提高效率保证安全性,也会用sass,less来编写css,浏览器在默认情况下也不能处理

3)实时监听开发过程,使用热更新

4)项目编码完成后,在部署之前需要对代码进行压缩处理

为了解决这些问题,使得开发者可以随意使用想用的技术栈进行项目开发,最终结果可以在浏览器直接展示,因此就会用到打包工具,我们项目使用的react,vue,angular等框架本身就集成了webpack,所以看似没配置,但是其实功能你已经在用了。

2、定义

是为现代js应用提供静态模块打包的工具

可以将不同类型资源按模块处理进行打包

打包后最终产出静态资源,最终产出的内容可以直接部署在静态服务器上使用

webpack支持不同规范的模块化开发,例如esmodule,commonjs,amd规范等

3、本地安装webpack+webpack-cli

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>

回到浏览器就不报错了

4、终端命令行配置入口entry和出口output

将index.js重命名main.js,再次执行npx webpack会报错,所以就需要用到一些配置

npx webpack --entry ./src/main.js终端执行这个命令就不会报错啦

npx webpack --entry ./src/main.js --output-path ./build终端执行这个命令修改输出目录

终端命令比较麻烦,所以可以通过一下方式:

终端执行npm run build即可

5、新建webpack.config.js文件,配置入口和出口

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 的值是一个绝对路径。你可以通过两种方式来实现:

  1. 使用绝对路径: 直接指定输出目录的绝对路径,例如 /user/project/dist

  2. 使用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就没问题啦

6、为什么使用loader?

不是所有的文件都能被打包,就需要loader来进行文件的转换。默认只能打包js文件。

css-loader只是能让webpack可以识别我们的css语法,并不能在元素上生效对应的css样式,需要安装style-loader

6.1、css-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 就没有报错啦,而且页面上样式已经生效了

6.2、style-loader

作用就是在界面中生成一个style标签

新建login.less文件

安装npm i less -D

less编译为css?

npx less ./src/css/login.less loginLessToCss.css终端执行命令后,会生成一个loginLessToCss.css文件,就是Less文件所编译成的css文件

但是不可能说我有好多个less文件,都这样执行命令,所以安装less-loader

6.2、less-loader

7、项目工程化,兼容性:css js 一些特性如何实现兼容?到底要兼容哪些平台(caniuse.com是根据这个网站看的)?

node-modules里有一个包browserlist,配置需要兼容的平台

终端执行npx browserslist命令可以得到符合条件的平台

也可以新建.browserslistrc文件

8、postcss?做一些兼容性处理  browserlist提供条件
8.1、postcss是什么?

用JavaScript工具和插件转换CSS的工具。它的主要功能是将CSS代码转换为抽象语法树(AST),然后通过插件对AST进行操作和转换,最后再将AST转换回CSS代码。PostCSS的灵活性使得开发者可以编写自定义的插件来处理各种CSS相关的任务,比如自动添加浏览器前缀(autoprefixer插件)、支持新的CSS语法等。利用js转换样式的工具

8.2、如何使用?

安装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);

}

8.3、使用场景(样式无法做到兼容)

这三个样式不是所有的浏览器都能兼容,所以希望有这么一个工具帮我们自动添加前缀,实现兼容

安装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文件里就有兼容处理了

9、postcss-loader,兼容css样式,比如加前缀

当css文件中有一些可能在不同浏览器是不能做到完全兼容的样式时,做一些特殊处理

这时候安装npm i postcss-loader

webpack配置文件中修改加了postcss-loader,打开浏览器页面发现没有加上前缀,是因为我们需要添加插件

10、postcss-preset-env,不同插件的集合

当我们修改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

11、importLoaders属性

当我们有个css1文件,这个文件里没有需要兼容性处理的代码,而另一个文件css2里有需要做兼容性的代码,css1文件内通过@import './css2.css'的方式引入,发现并没有做兼容性处理,原因是因为先postcss-loader,然后css-loader才会处理@import 或者url()这种的css文件,他会自动的把他替换为require语法,但是css-loader并没有兼容处理的能力,所以导致这个问题,这时候就需要引入importLoaders

12、file-loader打包图片(一种img标签设置src,一种css设置background:url)

方式一: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,发现没问题了

12.1、如何对file-loader打包后的图片的结果进行一些处理?

执行npm run build后查看dist文件夹

13、url-loader处理图片

安装npm i url-loader -D

执行npm run build,页面展示没问题,但是dist下边没目录了

13.1、file-loader与url-loader处理图片的区别?

file-loader:把我们当前的图片名称或者路径返回,及打包后的图片资源直接拷贝到dist目录下

url-loader:把我们要打包的图片资源以base64uri的方式加载到代码中

可以审查下元素

url-loader好处就是减少了请求的次数,但也有风险,如果图片资源较大,那这种方式就不好了

在url-loader内部可以调用file-loader

14、asset(无需安装,webpack5自带)处理图片

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)局部配置

15、asset处理图标字体

新建font文件夹存放iconfont库

新建Font.js

index.js文件中引入

npm run build发现报错了,因为缺少可以处理iconfont的loader

配置loader

npm run build 没问题

16、webpack插件plugin

loader:是对特定的模块类型做一个转换

插件:可以做更多的事情,可以用于执行范围更广的任务。包括:打包优化,压缩处理,资源管理,注入环境变量。

想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中

16.1、clean-webpack-plugin:自动清空dist文件夹

安装npm i clean-webpack-plugin -D

npm run build就会自动清空dist文件夹了

16.2、plugin:html-webpack-plugin 自动打包生成静态资源xxx.html文件

dist文件夹下会自动生成静态html文件

新建public文件夹,下边新建index.html

webpack文件配置

npm run build后dist文件夹下的index.html

17、定义常量DefinePlugin,webpack自带,设置BASE_URL

比如vue项目生成的public文件夹

给我们这个index.html替换下

npm run build会报错

原因是因为会把./原封不动拿过来给BASE_URL,但是我们期望的是个字符串,所以说加个""就可以了

18、babel:转换在项目中使用的JSX,TS,ES6+这些语法

为什么前端会用到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这样的一个预设集合的存在,一窝端

18.1、@babel/preset-env预设集合

npm i @babel/preset-env -D

npx babel src --out-dir build --presets=@babel/preset-env

18.2、babel-loader 转浏览器不支持的js语法

一个一个引入太麻烦,直接把预设放在这

那什么浏览器会被兼容这种转换的规则呢,就得说回.browserslistrc文件了,跟这里边的有关系

那还有一个可以配置的地方

target这个更优先

简洁方法,新建一个babel.config.js

19、polyfill:打补丁  webpack5优化打包速度,所以移除了,需要的话得安装

是什么?当代码遇见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时要配置下

20、plugin: copy-webpack-plugin 资源拷贝 例如public文件下的favicon.icon的拷贝,不需要打包,直接帮我拷贝一下就好

npm i copy-webpack-plugin -D

插件:uglifyjs-webpack-plugin 通过 UglifyES 压缩 ES6 代码

用于在打包过程中对 JavaScript 代码进行压缩和混淆,以减小文件体积并提升加载性能

设置 parallel: true 时,它会启用并行压缩,即使用多个进程来加速代码压缩过程。这在大型项目中特别有用,可以显著减少压缩时间。

插件:webpack-bundle-analyzer 是一个用于可视化分析 Webpack 输出文件体积的工具。

它可以帮助你了解各个模块在打包后的体积情况,从而优化你的打包配置和代码结构,减小文件体积,提升网页加载速度。

插件:mini-css-extract-plugin 用于将 CSS 从 JavaScript 中提取出来的 Webpack 插件。它能够将 CSS 代码从打包生成的 JavaScript 文件中提取出来,形成一个独立的 CSS 文件,有助于优化网页加载性能和缓存利用率。

插件:compression-webpack-plugin:开启GZip压缩

21、webpack-dev-server

是一个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文件夹,是因为放在内存了,而不是磁盘的读写

22、webpack-dev-middleware

安装npm i express webpack-dev-middleware

新建server.js文件

这时候通过localhost:3000也可以访问页面啦

23、webpack5中的HMR模块热替换功能

浏览器只需要对局部发生变化的数据进行展示即可,

在开发阶段应该把.browserslistrc内容给屏蔽掉,再加上热更新功能

默认还是刷新整个页面进行工作的,但是我们不期望这样,所以应该在入口文件中把想要进行热更新的文件给他写上

24、react项目支持热更新功能

安装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发现都实现了热更新

25、vue项目支持热更新

安装 npm i vue@2.6.14 vue-template-compiler@2.6.14 -D

新建App.vue文件

vue-loader15版本之前可以直接处理,之后需要自己加个插件

26、path
1)output中的path与publicPath

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就会有问题

2)devServer中的publicPath:告知浏览器指定本地服务所在的目录

得一样

publicPath这里是/lg,那不可能通过http://local:8080来访问到,得再加个/lg

contentBase有这样一个使用场景,在public文件夹下有一个工具js文件,这个文件我不希望被webpack打包,只是帮我拷贝一下就行,但是打包后的index.html又引用到了这个工具文件,这时候就得通过contentBase来找path.resolve(__dirname, 'public')绝对路径,因为这个工具文件在public下,跟contentBase配套的一个配置,用于监控资源是否更新,watchContentBase: true

27、dev-Server的配置

hotOnly的存在原因:当页面中存在很多组件,当一个组件可能出现一些语法错误时,当我们发现问题并且修改后,发现会因为这一个组件导致整个页面进行了刷新,这样不好,所以出现了hotOnly:true

port:4000重启一个端口

open:true会自动打开页面

compress:true压缩,性能提升

historyApiFallback: true的使用场景,页面通过路由实现页面跳转,当从home跳转到about,再刷新about页面会找不到,这时候加上这个配置就可以了

28、devServer本地开发设置proxy请求代理

4000端口的服务去请求服务端的接口,然后把数据给前端

29、resolve配置模块解析规则

分为三种情况:

绝对路径

相对路径:根据路径,路径确定了,往后就看他是文件夹还是文件,文件就看有没有明确后缀,如果没有,就是extensions里的.js,.json,如果是文件夹,默认会给他补全,index

模块:找node_modules下的模块就行

webpack配置

29.1、extensions:解析后缀名

29.2、alias:创建 import 或 require 的别名,来确保模块引入变得更简单

30、source-map

mode的值默认是production,npm run build后会比较优化,

如果改为mode: 'development',打包后会更加便于阅读,打包后的文件里会有个eval()的包裹,原因是因为当设置为development模式后,相当于加了个devtool:'eval'

devtool:控制是否生成,以及如何生成 source map

30.1、为什么需要source-map?

当我开发过程中如果语法有一些错误,执行npm run serve后会看到控制台报错,但是报错的定位是打包后的js文件,我们无法快速定位到问题出在哪里,这时候就需要source-map了,是个映射技术,可以依据转换之后的代码,返还成原代码

便于调试,打包后会多一个.js.map

31、devtool详细说明

值:

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

32、ts-loader编译ts

全局安装npm i ts,会生成ts compiler解析器

终端执行tsc --init,当前目录下会生成tsconfig.json文件

安装npm i ts-loader

33、babel-loader编译ts

用到一个预设

npm i @babel/preset-typescript

babel-loader在代码打包npm run build时如果有语法错误不会报错,但是在运行阶段会报错

ts-loader在代码打包npm run build时如果有语法错误会报错

解决办法?

使用babel-loader

在package.json文件内新增

这样就会在打包之后进行ts检查

34、区分打包环境

webpack-merge

项目代码:

const projectName = process.env.ENV_PROJECT || process.argv[2]; // 项目名称

process.argv

webpack.base.config.js

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值