1.0.0 • Published 2 years ago

webpack_qianfeng v1.0.0

Weekly downloads
-
License
-
Repository
-
Last release
2 years ago

自定义vue脚手架

1、安装webpack

1.1 全局安装webpack

不建议: 全局安装将锁死webpack

image-20220821003828822

image-20220821003902213

注意:webpack默认入口文件是__dirname/src/index.js

image-20220821010901130

image-20220821011059515

1.2 本地环境安装webpack

默认使用全局的webpack,要使用本地的webpack要用到npx

先从当前文件夹找,找不到再去node_modules里面找

image-20220821011616914

1.3 自定义webpack配置

查看所有webpack配置指令

image-20220821011937328

命令行方式

image-20220821012132739

配置方式

image-20220821012952373

2、webpack插件

作用:打包优化、资源管理

image-20220821013654299

2.1 HtmlWebpackPlugin

作用:根据模板生成打包后的html文件

image-20220821014047774

2.2 CleanWebpackPlugin

作用:每次打包前清除本地的dist文件夹

image-20220821015814941

原先情况如上所示

image-20220821015956330

最新版不需要该插件,只需output开启clean属性

image-20220821020234748

image-20220821020523601

3、搭建开发环境

3.1 mode

作用:改变环境变量NODE_ENV的值

image-20220821105103872

image-20220821105148843

3.2 devtool

作用:代码出错后可以快速识别出错文件区域

image-20220821105459424

image-20220821110242194

image-20220821110430901

image-20220821110559127

image-20220821110706338

解决办法:使用devtool配置source-map

image-20220821110939645

image-20220821111245674

image-20220821111209625

image-20220821111314175

3.3 watch

作用:监听任何已解析文件的更改

image-20220821112552225

使用命令行方式实现监听

image-20220821112920622

使用配置方式实现监听

image-20220821113218710

3.4 dev-server

作用:实时加载页面(live reloading)

image-20220821113834721

image-20220821114105127

image-20220821132423482

image-20220821123638349

注意:当目标html文件名不是index时,url后缀需要加上文件名

4、资源模块

image-20220821203634434

4.1 asset/resource

image-20220821205553981

image-20220821205643214

image-20220821205736254

image-20220821205800813

4.2 asset/inline

作用:导入文件,生成uri,打包后文件夹里面看不到文件,uri以base64形式存在

image-20220821212725148

image-20220821212937459

4.3 asset/source

image-20220821215250180

image-20220821215341077

4.4 输出文件名

4.4.1 assetModule

作用:配置打包后文件名规则

image-20220821210218937

思考:如何自定义打包后的资源文件名

image-20220821211101105

image-20220821210719407

4.4.2 generator

image-20220821211326059

image-20220821211533982

4.5 asset

作用:自动选择asset/resource或者asset/inline资源导入模式

原理:默认情况下,资源体积大于8k会创建一个资源,小于8k会生成inline资源

image-20220821220532911

image-20220821220735991

思考:如何修改webpack默认的规则?

image-20220821221402377

image-20220821221504702

image-20220821221900318

image-20220821222404980

5、loader

5.1 css相关

需要用到style-loader、css-loader

image-20220821235011904

image-20220821235814259

image-20220821235953792

image-20220821235714866

5.1.1 抽离css

情形:默认情况下,导入的css会转换成js

需要抽离css,需要借助mini-css-extract-plugin

image-20220822002917043

image-20220822003327826

image-20220822001652577

image-20220822001935449

思考:如何指定打包后的css存放文件夹及文件名

image-20220822002631854

5.1.2 压缩css

压缩css,需要借助css-minimizer-webpack-plugin

image-20220822003400462

image-20220822004404837

5.1.3 css加载图像

之前已经搞好了style-loader、css-loader不需要额外配置

image-20220822010833662

image-20220822011023656

image-20220822010949165

5.1.4 css加载字体

image-20220822214236717

image-20220822214136685

image-20220822214030752

5.1.5 css模块化

image-20221011014432097

5.2 json相关

5.2.1 json

webpack可以直接导入

5.2.2 json5

image-20220822225744619

image-20220822230515527

image-20220822230658576

image-20220822230753255

5.3 babel相关

image-20220822231830055

image-20220822231924572

image-20220822231958377

思考:如果浏览器不支持es6代码怎么办?

需要借助babel将es6转换为es5

babel三件套:@babel/core、@babel/preset-env、babel-loader

image-20220822232727547

image-20220822233423999

image-20220823000844533

image-20220823000942377

image-20220823001148339

如上所示,浏览器正常运行

注意:老版本可能会出现没有generatorRuntime的情况

@babel/plugin-transform-runtime、@babel/runtime

image-20220823003309976

image-20220823003044566

6、代码分离

6.1 入口起点

缺点:共享的代码会分别引入到各自的bundle中

image-20220823004828913

image-20220823004925899

6.2 防止重复

作用:通过配置entry,把公共的代码抽离成单独的chunk

image-20220823010202721

image-20220823010348844

6.3 splitChunk方式

webpack自带splitChunks插件

image-20220823011001197

image-20220823011432266

6.4 动态导入

image-20220823012604266

6.5 懒加载

作用:体现在需要某前置条件触发后才加载

image-20220823014408144

image-20220823014338915

6. 6 预加载

webpackPreload或者webpackPrefetch

image-20220823014905179

image-20220823014822690

6.7 指定输出文件夹

业务场景:将所有js文件放到scripts文件夹里面

image-20220916012558411

7、缓存

7.1 易变资源-输出文件名

作用:部署新版本时,没有更改资源文件名,浏览器会误认为你没有更新。

image-20220916005344680

image-20220916005434344

7.2 稳定资源-缓存组

作用:将node_modules中的所有依赖打包到同一个js文件中

image-20220916011633755

8、环境拆分

情形:目前只能手动修改mode来切换环境,开发环境和生产环境有很大区别。

区别:开发环境不需要缓存、生产环境需要设置公共路径等

8.1 公共路径

image-20220918233438144

默认使用相对路径

配置publicPath

image-20220918233825781

打包后link加上了公共路径

image-20220918233745933

8.2 环境变量

image-20220918234433233

image-20220918234657200

image-20220918235439677

image-20220918235558965

image-20220919000443466

本质:配置--env是往webpack环境变量对象里面添加属性,默认为{WEBPACK_BUNDLE: true, WEBPACK_BUILD: true}, 新增的环境变量属性默认值为true,设置环境变量值如下所示

image-20220919000142663

8.2 生产环境压缩

image-20220919000847056

原因:打包后的js文件没有压缩

image-20220919003558349

解决办法:terser-webpack-plugin压缩js文件

terser-webpack-plugin

image-20220919001710457

image-20220919002822591

image-20220919003800728

image-20220919004001577

问题:还是存在文件超出指定大小的提示

解决办法:配置webpack的performance

image-20220919011052441

image-20220919010907178

9、配置文件拆分

9.1 拆分文件

image-20220922005607241

image-20220922005707946

9.2 合并配置文件

image-20220922012254942

如上所示拆分出三个文件

需要借助webpack-merge这个包

image-20220922014747338

image-20220922014908021

10、vue环境搭建

10.1 vue2搭建

安装vue@2.6.14和vue-loader

image-20220923005821396

image-20220923005912640

配置vue-loader

image-20220923010105729

image-20220923010216089

配置vue入口文件

image-20220923010417347

image-20220923010553376

image-20220923010701507

注意:此时还是无法编译vue文件

需要安装vue-template-compiler且版本要一致

image-20220923013129009

10.2 Naruto

Naruto: 即vue2.7版本

image-20220927002226026

注意:vue2.6.14升级成2.7是vue-template-compiler版本不变

image-20220927002618715

通过查看vue-template-compiler发现,还是有对应2.7版本

image-20220927003237166

image-20220927003319730

10.3 vue3

npm install vue-loader@next
npm install vue@next

image-20220927004238022

npm install @vue/compiler-sfc

image-20220927004503620

vueLoadPlugin的引入稍有差异

const {VueLoaderPlugin} = require('vue-loader/dist/index');

image-20220927005632984

11、sourceMap

具体看官方文档

image-20220928012459101

image-20220928012543233

image-20220928012615924

建议:开发环境,inline-source-map,生产环境:source-map

Eval

特点:每个模块都会用eval包裹起来执行,仅开发环境支持,sourceURL指向资源路径

image-20220930002356840

image-20220930002453708

source-map

特点:生成一个sourceMap文件,sourceMappingURL指向资源路径

image-20220930005311528

sourceMappingURL

image-20220930005623670

Hidden-source-map

特点:和source-map一样,只是不会生成注释

image-20220930010240035

Inline-source-map

特点:不会单独生成一个sourceMap文件

image-20220930011054594

Eval-source-map

特点:每个module被eval包裹,并且生成一个sourceMappingURL形式的sourceMap

image-20220930011514048

image-20220930011555626

Cheap-source-map

特点:生成map文件,只记录代码行数,不记录代码列数

image-20220930012359653

Cheap-module-source-map

特点:只是不显示列,排除各种loader对代码的影响

image-20220930013208601

12、dev-server

proxy

const http = require('http')

const app = http.createServer((req,res) => {
    if(req.url === '/api/hello') {
        res.end('hello node')
    }
})

app.listen(9000, 'localhost', () => {
    console.log('localhost:9000')
})
fetch('/api/hello')
    .then(response => response.text())
    .then(res => {
        console.log('rs', res)
    })
    .catch(err => {
        console.log('err', err)
    })
devServer: {
        // static: './dist',
        hot: true,
        open: true,
        proxy: {
            '/api': 'http://localhost:9000'
        }
    },

image-20220930020216030

以上这种方式是路径拼接方式

13、模块热替换、热加载

热替换:程序运行过程中,增删改模块,无需重新加载整个页面, 即hot

举例:动态生成5个绿色矩形,代码修改css样式为红色,开启hot后会5个绿色矩形变红色矩形,而不是整个页面重刷一遍。

原因:css-loader已经支持module.hot

热加载:修改模块后,自动刷新服务和页面, 即liveReload

// 判断当前是否支持模块热替换(本质:检查devServer是否开启hot属性)  

console.log('是否支持模块热替换', module.hot)

// if(module.hot) {
//     module.hot.accept('某模块文件.js', () => {
//         console.log('这里是回调函数')
//     })
// }

image-20221008235011901

14、eslint

作用:一个扫描所写代码是否符合统一规范的工具。

注意:新版eslint初始化会出现下列问题

Need to install the following packages:
  @eslint/create-config

初始化配置

image-20221009000356742

image-20221009000552304

image-20221009000700326

image-20221009000802063

image-20221009000854205

image-20221009001154163

image-20221009001253702

image-20221009001456335

image-20221009002042288

"eslint-config-airbnb-base": "^15.0.0", // 选择的airbnb规范
"eslint-plugin-import": "^2.26.0", // 模块化方式选择了import、export
"eslint-plugin-vue": "^9.6.0", // 选择的vue框架
{
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "plugin:vue/vue3-essential",
        "airbnb-base"
    ],
    "overrides": [
    ],
    "parserOptions": {
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "plugins": [
        "vue"
    ],
    "rules": {
    }
}

检查指定文件

image-20221009004007078

npx eslint ./src/main.js

image-20221009010322790

保存即检测

需要借助webpack的eslint-webpack-plugin,老版借助eslint-loader

image-20221009014152232

image-20221009014901818

image-20221009015005562

15、husky

作用:代码提交时做eslint验证。

git-hooks

image-20221009233544498

image-20221009234047555

git有如上所示那么多hook

image-20221009234913237

image-20221009235053185

需要新建一个pre-commit文件

vim pre-commit
按下键盘i键进行输入
按下键盘esc退出编辑
按下键盘冒号,输入wq保存并退出

编辑文件

image-20221010000638832

在commit之前会执行pre-commit, 但是pre-commit文件没有设置执行权限,故而报警告

image-20221010001104910

进入hooks文件夹,能看到pre-commit文件

chmod +x ./pre-commit  

image-20221010001654667

Pre-commit执行eslint

image-20221010002052758

即在pre-commit文件夹中输入cli指令即可

image-20221010002633668

虽然起作用了,但是pre-commit文件夹在.git/hooks里面,属于隐藏文件,不会提交到仓库

git config core.hooksPath .mygithooks

修改hooks路径

image-20221010005353556

husky

作用:不用手动修改hooks路径

npm install husky -D // 安装husky
npx husky install // 开启git-hooks

image-20221010011641867

16、postcss

作用:用js工具和插件转换css代码的工具。

webpack已经依赖了postcss, 只需安装postcss-loader

browserslist

作用:获取当前主流浏览器及各css属性兼容情况

image-20221011012921006

postcss插件

如autoprefixer为css属性添加前缀

image-20221011013500446

image-20221011013612214

image-20221011013701088

image-20221011013752928

如上所示通过autoprefixer为css属性添加前缀。

image-20221011014032086

17、模板导入资源

导入public下文件

index.html只能导入public文件夹里面的静态文件

image-20221012001922685

此方法不建议使用

Copy-webpack-plugin

作用:将不需要打包的文件或文件夹复制到打包后的内容里面

image-20221012005419209

尝试是否能在index.html里面导入文件???

image-20221012005706500

image-20221012005749128

image-20221012010142505

image-20221012010251188

18、处理web worker文件

注意:直接靠相对路径来引入js文件是不行的。

image-20221016224357536

image-20221016233228528

即使用文件解析路径也不行

解决办法

安装worker-loader

npm install worker-loader --save-dev

webpack配置如下所示

image-20221017005030550

image-20221017004840516

image-20221017005128825

image-20221017005209724

image-20221017004556019

如上所示正常使用

image-20221018014012871

打包后在主chunk里面可以看见引入文件情况如上所示

npm.io

官网有介绍

19、集成typeScript

npm install typescript ts-loader -D

项目根目录下创建tsconfig.json

npx tsx --init

image-20221017011247743

配置tsconfig.json, 即额外开启

"rootDir": "./src", 
"outDir": "./dist",

image-20221017012034247

image-20221017012115704

image-20221017012137136

注意:ts中引入其它文件会报错

image-20221017012641172

https://www.typescriptlang.org/

在typescript上查找对应依赖名,找对应依赖需要安装的类型包

image-20221017013301225

image-20221017013436011

npm install --save-dev @types/lodash

image-20221017013920577

20、集成多入口html

常规配置下只有html文件导入打包后的所有资源(css/js)文件

image-20221018010915473

image-20221018011139350

配置模板标题

image-20221018011632815

image-20221018012317045

image-20221018012432287

模板指定chunks

制定该引入的chunks

image-20221018012743529

image-20221018012835588

下面尝试打包后不引入该chunk

image-20221018013745947

image-20221018013700779

多模板多页面

即创建多个HtmlWebpackPlugin实例即可

image-20221018014733437

image-20221018015036574

image-20221018015150381

21、treeShaking

Treeshaking: 一个术语,移除JavaScript上下文中未被引用的代码(即dead code)

webpack5默认treeShaking,webpack4没有treeShaking

npm.io

官网有介绍

22、sideEffects

作用:告诉webpack代码有副作用,不应该随便删除,默认为true

以直接引用的css文件为例

image-20221022004954387

image-20221022005016828

image-20221022005344638

image-20221022005421558

指定某文件类型不被sideEffect掉

image-20221022010841016

image-20221022010910725

image-20221025003212752

官网有介绍

23、PWA渐进式网络

PWA:渐进式网络程序,服务挂了也能能访问网页

http-server

采用http-server

image-20221024011423026

image-20221024011915570

image-20221024012008919

Dev-server写入硬盘

image-20221024013330528

添加workbox

workbox:谷歌浏览器提供的浏览器端缓存数据的工具

需要借助workbox-webpack-plugin

image-20221022012935394

image-20221024010422649

new WorkBoxPlugin.GenerateSW({
	clientsClaim: true, // 快速启用sw
	skipWaiting: true, // 跳出等待
	maximumFileSizeToCacheInBytes: 5242880, // 允许缓存最大文件大小
})

注意:开发环境如果使用该插件,会因为热更新报如下警告

WARNING in GenerateSW has been called multiple times, perhaps due to running webpack in --watch mode. The precache manifest generated after the first call may be inaccurate! Please see https://github.com/GoogleChrome/workbox/issues/1790 for more information.

image-20221024020348032

原因:上面例子用了dev-server写入硬盘方式生成dist文件夹及内容

注册serviceWorker

判断浏览器是否支持service-worker,只需navigator.serviceWorker

image-20221024015218412

image-20221024024750225

image-20221024024852833

原因:service worker需要使用本地回环地址或采用https协议

image-20221025000833903

image-20221025000912628

如上所示,采用本地回环地址注册成功

尝试关闭server

image-20221025001537326

image-20221025001437494

查看浏览器已注册的service worker

chrome://serviceworker-internals/

image-20221025002118880

image-20221025003638034

官网有介绍

24、shimming预置依赖

webpack识别遵循es2015、commonJS、AMD编写的模块规范

一些第三方库会引用一些全局依赖,比如jquery中的$,因此这些库需要创建一些需要导出的全局变量

这些不合规范的模块需要预置依赖处理

ProvidePlugin

webpack内置的一个插件,自动加载模块并设置为全部依赖

下面以引入jquery为例

image-20221025015749266

image-20221025015931738

如上所示,就可以使用jquery了,注意jquery版本要大于2.xx

imports-loader

作用:默认以commonjs方式模块化导入非模块化js文件,并可指定模块内最外层全局变量的值

案例:将包里面this指向window

需要单独安装imports-loader

image-20221025210029500

image-20221025021553046

image-20221025021704804

image-20221025021844249

image-20221025210302093

官网有介绍

Exports-loader

作用:按loader提供的规则,将非模块化且非导出的方法或变量模块化导出

image-20221025213120051

image-20221025213337727

image-20221025215206574

image-20221025215325783

image-20221025215412268

image-20221025215647167

25、polyfill垫片

@babel/polyfill

需要安装@babel/polyfill依赖

image-20221025222407208

image-20221025230438170

{
  test: /\.js$/,
    exclude: /node_modules/,
      use: [
        {
          loader: 'babel-loader',
          options: {
            presets: [
              [
                '@babel/preset-env',
                {
                  targets: [
                    'last 1 version',
                    '> 1%'
                  ],
                  useBuiltIns: 'usage', // 按需添加@babel-polyfill
                }
              ]
            ]
          }
        }
      ]
},

image-20221025230320885

Core-js

image-20221025231345810

image-20221025223443866

image-20221025232205411