webpack学习笔记

webpack:

 

课程跟练代码: https://github.com/joyful2/webpack-learn.git

 

todo:

1 webpack官方文档查漏补缺(常用功能)

2 使用webpack编码符合业务的配置
3 常用loader,plugins的了解和使用
 
 
学习目标:
1 知道能做什么,不能做什么
学会webpack常用功能
2 了解大致原理
知道webpack怎么工作,webpack结果文件怎么阅读
3 根据业务合理配置webpack
 
学习注意:
1 不要死记写法,记住规律
2 不要试图学会所有功能
3 了解原理,但没必要深入原理
 
课程安排: 概念讲解 + 基本使用演示 + 进阶使用演示(直播)+ 案例讲解(直播)
 
webpack:快速方便的完成项目 =》 工程化(系统化,模块化,规范化。自动化?)
 
webpack主要功能:
编译:js,sass,css,typescript
打包:压缩,打包
图片等资源的处理
tree-shaking等优化js工具
webpack-dev-server,eslint,热更新等
 
前端模块化:
模块化方案: commonjs(nodejs的规范) AMD/CMD/UMD(民间模块化规范) ES6 Module(官方模块化规范)
 
 
webpack配置文件: 我们的工作对象,决定webpack如何打包,打包成啥样。
 
webpack自身只能打包,且只能处理js,因此需要loader和plugin
 
 

核心概念: entry; output; loader; plugin

entry: 'app.js'    打包入口。 多个入口:entry: [app1.js,app2.js]; 多个入口和多个出口:entry: { app:'app.js', app:'app2.js'}

output 

loader: 用于处理各种后缀的文件,通常是编译用。

plugin: webpack的额外扩展。比如优化代码,提供功能。

 

常用loader:

 
 
常用plugin:
 
 
 --------------------------------------------------------------------------------------------------------------
 
无配置文件打包:webpack-cli --entery <entry> --output <output>
指定配置文件打包:webpack --config myconfig.js

全局webpack和局部webpack:

执行webpack:默认会用全局webpack,依据webpack.config.js来打包
 
如何使用局部webpack: 用npm.scripts里配置命令行,就会优先使用局部webpack打包(scripts:{build: 'webpack'})

 

注意webpack版本问题,以及全局webpack和局部webpack版本不一致的问题, webpack打包报错很可能是webpack版本不支持配置文件的配置
 
 --------------------------------------------------------------------------------------------------------------

 

js的编译:

babel-loader无法编译所有的es6语法,还需要babel-polyfill
babel-polyfill原理: 把es6方法全部用es5实现了。所以会让文件体积较大。适合于项目开发。无需配置,引入即可用。
babel-transform-runtime: 只会对使用到的es6方法进行es5的实现,文件体积较小,适用于框架开发。配置: plugins: ['@babel/tranform-runtime']

 

 

 
babel-preset:

 

 

.babelrc: babel编译的配置文件(study: 官网学习如何编写,可在loader的npm或github上查询)
tsconfig.json: typescript的编译配置文件(study: 官网学习如何编写,可在loader的npm或github上查询)
 
一些规律:
1 装loader 2 webpack配置文件写loader 3 写loader的配置文件

 

 

webpack 的mode 决定了process.env.NODE_ENV

配置:

webpack --mode=development

// webpack.development.config.js
module.exports = {
  mode: 'development',
};



loader原理: “嘿,webpack 编译器,当你碰到「在 require()/import 语句中被解析为 '.txt' 的路径」时,在你对它打包之前,先 use(使用) raw-loader 转换一下。”

webpack打包原理: 从入口开始打包,如果配置了loader,则在当引入loader匹配的文件后缀文件时,用loader预处理(转换)相应文件后再打包!

 
注意: 正则表达式不要加引号!如下: test:/\.js$/
  
------------------------------------------------------------------------------------------------

Webpack 有大量的配置项,可能会让你不知所措,请利用 webpack-cli 的 init 命令,它可以根据你的项目需求快速生成 webpack 配置文件,它会在创建配置文件之前询问你几个问题。

npx webpack init

------------------------------------------------------------------------------------------------------------------------
webpack打包让项目引入和运行css需要:1 先用less-loader编译处理转为css(less, sass的处理) 2 通过css-loader让js能引入css 3 用style-loader让css正确地以style标签的形式插入页面 所以使用loader的顺序不能错:
    use:[
          {
            loader:'style-loader',
          },
          {
            loader:'css-loader'
          },
          {
            loader:'less-loader'
          }
        ]
注意: use数组里后边的先执行



style-loader的核心配置(study):

css-loader的核心配置(try
):

css modules: https://blog.csdn.net/snowball_li/article/details/121478262
-----------------
把css打包成一个文件todo: extract-text-webpack-plugin(若是webpack4及以上则是用extract-text-webpack-plugin@next)依赖于局部webpack,需安装局部webpack.然后把打包后的css文件手动引入的到html

使用 html-webpack-plugin(try): 1 这将自动包含捆绑的 js 以及 ExtractTextPlugin 提取的 CSS 2 html-webpack-plugin 为应用程序生成一个 HTML 文件,并自动将生成的所有 bundle 注入到此文件中。.

todo
1 解决extract-text-webpack-plugin配置问题(估计是改成了mini-css-extract-plugin MiniCssExtractPlugin
2 使用HotModuleReplacementPlugin实现热更新


post-css的插件: poss-css poss-loader autoprefixer postcss-cssnext
autoprefixer: 处理兼容性(加上-webpack-, -ms- 等前缀)eg: display: -webpack-box;
browserlist的配置:可放到package.json里或.browserlistrc文件里,这样babel,和css相关loader都会读这个配置,不需多个地方写,避免多处配置不统一的问题
package.json:

 

有些loader的使用在webpack官网都能搜到,比如用autoprefixer,搜一下,就能查到如何配置

postcss-cssnext(todo): 使用下一代css语法

环境变量(try
):" https://webpack.docschina.org/guides/environment-variables/

待办:
1 完成的try和 todo,
2 了解如上这些loader都是干嘛的

3 在项目中看这些loader的使用,没用的自己用到项目里去!


------------------------------------------------------------------------------------------------------------------------

:root 是 css 的一个伪类,表示文档根元素。在 :root 中声明相当于全局属性,只要当前页面引用了 :root 所在文件,都可以使用 var() 来引用。

eg:把项目的主题颜色,声明在 :root 中。

:root {
--theme-color: #DF4270;
}

------------------------------------------------------------------------------------------------------------------------

htmlwebpackplugin(todo: 1 解决不生效的问题 2 用到项目里):打包html,指定自动引入css,js等

配置:

 

 --------------

环境:

开发环境

env: 是开发自己定义的

    "build": "webpack --env pro --config webpack.common.js",
实践:把开发和生产都需要的公共配置写到webpack.common.js,然后分别写开发配置和生产配置;最后依据 env是开发还是生产来用webpack.common.js合并不同配置。 
 

NODE_ENV也是开发自己定义的

"build": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js ",

 

 mode: 

webpack4以上支持指定mode,会走内置的配置,依据mode来走不同配置打包!(比如production模式会自带压缩和tree-shaking)

webpack --mode producton/development

开发模式:eslint, webpack-dev-server, source-map等调试功能。 不需要压缩,tree-shaking等功能

生产模式: 和开发模式相反

 -----------------------------------------

webpack-dev-server: 

作用: 模拟线上环境进行项目调试的工具

常用功能:1 开启前端本地服务 2 在浏览器中显示编译错误(overlay?)  3 接口代理  4 热更新(hot)5 路径重定向(historyapifallback? 对404的处理)

webpack-dev-server也是一个命令工具,有全局和局部之分: 命令行执行 webpack-dev-server会走全局的,而通过npm run dev运行scripts里的 webpack-dev-server 就会走局部的!

 

devServer的常用配置:

 

historyApiFallback 访问未配置的路由时,404的处理。

lazy: 懒编译。 访问某个入口时才编译对应文件,提高打包速度

overlay: 把错误显示在页面上(给页面加一层遮罩显示错误)

 

todo: 

devServer的配置随着版本都改了,抽时间看看最新配置,并手动尝试!

inline是干嘛的?

 -----------------------------------------

proxy:

    proxy:{
      '/category':{
        // 对于 包含 '/category' 的请求路径, 都给转发到 https://study.163.com  的域名去 , 然后把实际的请求url拼接在该指定target的后面
        target:'https://study.163.com',
        changeOrigin:true, // 跨域
        pathRewrite: { '^/category/480000004222002': '' }, // 把最终路径中 key路径匹配到的 部分 都替换为 value部分
      }
    }
 

hot热更新:

热更新和extractTextCss不兼容,可配置disabled掉 extractTextCss

 

  // 1 热更新只对css和js有效,html文件的改动无效 2 默认是liveReload
    hot:true,
    hot:'only',// 不liveReload ,不刷新页面,保留状态
 
// hot:'only' 配置情况下,必须要如下代码,才能支持js的热更新,而且是 只热更新,不liveReload.    
if(module.hot){
  module.hot.accept()
}
 

source-map: 定位到错误在源代码的位置(而非打包后的位置)

开发和生产使用不同模式:

 
 -----------------------------------------

webpack原理:

1 webpack是由node实现,也是基于node环境(因此是commonjs规范),和node的文件操作系统。

2 webpack打包的实现,就是用node读取文件,然后进行一些字符串处理后,再用Node写入文件

 

 打包流程:

 

loader原理:本质是一个方法,对文件进行字符串处理转换后,return出去

 

自定义loader: webpack官网有详细讲解

 


 -----------------------------------------

webpack打包结果文件分析:

 

 

 

  -----------------------------------------

dev-server原理: 

 

 热更新的原理:

 

 
  -----------------------------------------

 WebSocket 是一个协议,前端和服务器端可以建立起一个长连接,服务器也可以主动向客户端推送消息

 

图片处理loader:

file-loader:支持图片资源的引入

url-loader: 是基于file-loader的二次封装,可代替file-loader。支持将小图片(其他类型文件也可)转为base64格式,从而减少请求数

img-loader: 压缩图片等  imagemin等一系列插件的使用

 

常见的问题:

1 找不到路径: 需要配置outputPath或publicPath

2 命名的问题

   -----------------------------------------

html引入图片:

 

webpack雪碧图

实现:

post-sprites: 自动化,但会把所有css引入的图片拼接为雪碧图。

webpack-spritesmith: 可以指定打包哪个目录的图片,且能依据生成的css进行调整

 

共同问题: 都是把原文件(未压缩)拼接成雪碧图,然后定位也是根据原文件(定位不准确)。适用于图标,不适合大图片。

 

其他资源文件的引入:

 

规划路径:使用outpath和publicPath

 

未练习的位置: 18:27-26min

 

todo:

1 自己配置webpack实现引入阿里巴巴图标iconfont(使用url-loader或file-loader)

 

---------------------------

 webpack打包原理:

 

诉求:

1 缩小代码体积 (提取公共资源)

 

代码分割: 

1 提取公共模块(多页应用): 第三方依赖,公共模块等单独提取出来,以免重复打包增大体积

2 拆分应用,异步加载:缩小体积,提高首屏加载速度 

3 为了业务代码更纯净:不希望业务代码里混入第三方依赖代码,或webpack配置代码。把他们拆分出来(app.js, vendor.js, manifest)

 

实现:

 

manifest:

 

 

版本差异: 

webpack3使用commonChunksPlugin

webpack4使用SplitChunksPlugin(内置到 optimization.splitChunks配置)

 

 

用clean-webpack-plugin清除上次打包生成的代码(todo: 用到项目里)
 

---------------------------

 

webpack4代码分割配置

 

异步加载:代码会单独打包为一个文件

// import写法
// 通过 webpackChunksName 指定打包后的文件名
import(/* webpackChunksName:'ma' */'./moduleA.js').then(function(res){
})
 
// require写法
moduleB依赖于 moduleA时,这么写:
require.ensure(['./moduleA'],function(){
  var mb = require('./moduleB.js')
})
 
 tree-shaking原理:监听 export流,将没用到的属性/方法去掉(若不是用export而是用的 module.exports 就无效,或 若import *引入了了全部,则也无效。) 注意:babel可能会编译export,导致tree-shaking无效,因此需留意babel配置,进行修改
导出和引入需要的写法:

 

 tree-shaking失效可能是因为babel把export编译了,因此需配置如下:

 

 

webpack4 默认了很多配置,减少了配置文件书写。比如代码压缩,tree-shaking等

webpack学习目标:把原理和流程弄明白即可,不需要完整地学习源码

 

node_modules依赖的编译:

1 通常成熟的依赖都会经过编译,不会直接用es6

2 若需要编译,也没成熟可替代的包(已编译的),就只能自己写webpack给他编译下

 

打包结果分析:

chunks: 代码块,webpack把js分割成了几块代码(不一定每个chunk都会打包为一个文件)

module: 模块,每个文件都是模块。包括js,图片都是模块 

命令:

 todo: 依据上图手动生成打包结果分析文件并分析!

 

 

官方分析网站 http://webpack.github.io/analyse

重点关注: 模块依赖有无错;打包时间长的模块;chunk里的module是不是对的;

 

 

 

打包速度优化:

打包速度可以优化的点:

一 项目本身:

1 减少依赖嵌套的深度

2 使用尽可能少的处理(少点loader,plugin等)

二 webpack层面

1 Dll处理: 第三方依赖打包很慢,可通过dll单独打包,不用每次打包,减少打包时间(how?

2 通过include减少loader范围

3,4,5等 其他如下图

 

Dll处理:

原理:Dll把不常改变的第三方依赖,单独只打包一次,后续每次打包业务代码时,不再打包dll里的代码。

 1 配置需单独打包dll的配置文件,如下图的webpack.dll.js. 然后webpack --config webpack.dll.js单独打包一次,生成打包后的代码和json配置

 

2 配置webpack,让每次打包读取上一步生成的json,打包时读取缓存,不重复打包配置的文件

 

 

todo: 用 prefetch 来提高打包性能,解决依赖链太长问题?

 

 

前端构建简史:

html,css,js => jQuery=>bootstrap=>Nodejs=>grunt/gulp(流处理)

 

 

todo:

1 公司项目里主应用代理子应用

2   publicPath的作用

3 自定义loader的学习(在webpack官网)

 

 

todo:

了解babel-loader,ts-loade的配置,不同版本需要搭配哪些其他工具一起用等
看公司项目的es6,typescript等的编译配置
 
 

posted on 2023-07-20 20:02  joyful2  阅读(40)  评论(0编辑  收藏  举报

导航