前端工程化 | 模块化开发及规范化标准

ES Modules基本特性

自动采用严格模式,忽略’use strcit’

每个ESM模块都是单独的私有作用域

ESM是通过CORS去请求外部JS模块的

ESM的script标签会延迟执行脚本

ESModules中可以导入CommonJS模块

CommonJS中不能导入ESModules模块

CommonJS始终只会导出一个默认成员

注意 import不是解构导出对象

Webpack

Webpack是一个现代JS应用程序的静态模块打包器(module bundler)

模块:模块化开发,可以提高开发效率,避免重复造轮子

打包:将各个模块,按照一定的规则组装起来

官网:https://webpack.js.org

特点

  1. 功能强大:打包 构建 发布Web服务
  2. 学习成本高

构建(转换):把不支持的代码,转成支持的代码

打包(合并):把多个文件合并成一个文件

Webpack的功能

  1. 将多个文件合并打包,减少http请求次数从而提高效率
  2. 对代码进行编译,确保浏览器兼容性
  3. 对代码进行压缩,减小文件体积,提高加载速度
  4. 检查代码格式,确保代码质量
  5. 提供热更新服务,提高开发效率
  6. 针对不同环境,提供不同的打包策略

Webpack核心概念

入口,出口,加载器,插件,模式,模块,依赖图

Webpack核心概念 入口

  1. 打包时,第一个被访问的源码文件
  2. 默认是src/index.js(可以通过配置文件指定)
  3. Webpack通过入口,加载整个项目的依赖

Webpack核心概念 出口

  1. 打包后,输出的文件名称
  2. 默认是dist/main.js(可以通过配置文件指定)

Webpack核心概念  loader(加载器)

  1. 专门用来处理一类文件(非JS)的工具

Webpack默认只能识别JS,想要处理其他类型文件,需要对象的loader

  1. 命名方式:xxx-loader(css-loader|html-loader|file-loader)以-loader为后缀

常用加载器:webpackjs.com/loaders

Webpack核心概念  plugin(插件)

实则loader之外的其它功能

Plugin是webpack的支柱,用来实现丰富的功能

命名方式:xxx-webpack-plugin(html-webpack-loader)以-webpack-plugin为后缀

常用插件:webpackjs.com/plugins

Loader和Plugin本质上都是npm包

Webpack核心概念  模式

用来区分环境的关键字

不同环境的打包逻辑不同,需要区分

三种模式

  1. development:自动化打包速度,添加一些调式过程中的辅助
  2. production:自动化打包结果
  3. none:运行最原始的打包,不做任何额外的处理

Webpack核心概念  模块

Webpack中,一切都是模块

Js模块 一段css一张图片 一个字体文件 ...

Webpack最佳实践

1.初始化项目

mkdir myproject $$ cd myproject $$ npm init -y

2.安装Webpack

npm install -D webpack webpack-cli

3.创建入口文件

myproject/src/index.js

4.执行打包(必须指定mode)

webpack ./src/index.js --output-path ./dist --mode=development

Webpack配置文件

配置文件是用来简化命令行选择的

配置前:webpack ./src/index.js --output-path ./dist --mode=development

配置后:webpack

默认配置文件名称是webpack.comfig.js

Webpack.comfig.js是以CommonJS规范进行组织的

使用webpack的过程,大部分就是跟配置文件打交道的过程

Webpack配置文件-常用配置项

  1. mode(模式)
  2. entry(入口)
  3. output(出口)
  4. module(模块配置-不同类型文件的配置-loader配置)
  5. plugins(插件)
  6. devServer(开发服务器的配置)

Webpack打包CSS

非JS文件打包,需要对应的loader

css-loader将css转化为js(将css输出到打包后的js文件中)

style-loader把包含CSS内容的js代码,挂载到页面的<style>标签中

引入CSS(import”./css/main.cs”)

安装(npm i css-loader style-loader -D)

配置

匹配后缀名:test/.css$/i

指定加载器:use:[‘style-loader’,’css-loader’]

loader执行顺序:先右后左(先下后上)

Webpack打包less

引入less

import "./css/main.less"

安装

npm i less less-loader -D

配置

匹配后缀名: test:/.less$/i

指定加载器:use[‘style-loader’,’css-loader’,’less-loader’]

将CSS打包成独立的文件

安装插件

npm i mini-css-extract-plugin -D

引入插件(webpack.config.js)

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

替换style-loade(use:[‘MiniCssExtractPlugin.loader’,’css-loader’])

style-loader:将css打包到style标签中

‘MiniCssExtractPlugin.loader’:将CSS打包到独立文件中

配置插件:(new MiniCssExtractPlugin({}))

添加样式前缀

安装

npm i postcss-loader autoprefixer -D

配置webpack.config.js

use:['MiniCssExtractPlugin.loader','css-loader','postcss-loader']

新建postcss.config.js

plugins:[require('autoprefixer')]

配置需要兼容的浏览器

Package.json中指定browserslist

校验CSS代码格式

安装

npm i stylelint stylelint-config-standard stylelint-webpack-plugin -D

引入

const StylelintPlugin = require('stylelint-webpack-plugin');

配置

new StylelintPlugin({})

指定校验规则(在package.json中指定stylelint)

"stylelint":{"extends":"stylelint-config-standard"}
 

压缩CSS

安装

npm i optimize-css-assets-webpack-plugin -D

引入

OptimizeCssAsseptsPlugin  = require('optimize-css-assets-webpack-plugin');

配置

new OptimizeCssAssetsPlugin()
 
Webpack打包html
Html-webpack-plugin
生成html文件(用于服务器访问),并在html中加载所有打包的资源
指定html模板,设置html变量,压缩html

安装

npm i html-webpack-plugin -D
 

Webpack编辑JS

目的:将ES6+转换成ES5,保证JS在低版本浏览器的兼容性

安装

npm i babel-loader @babel/core @babel/preset-env -D
 

@babel/preset-env只能转译基本语法(promise就不能转换)

@babel/polyfill(转译所有JS新语法)

npm i @babel/polyfill -D
import '@babel/polyfill'   //入口文件中引入

core-js (按需转译JS新语法)

安装

npm i core-js -D

配置

按需加载 useBuiltlns: ’usage’

指定版本 corejs:3

Webpack校验JS代码格式

安装

npm i eslint eslint-config-airbnb-base eslint-webpack-plugin eslint-plugin-import -D

eslint(校验JS代码格式的工具)

eslint-config-airbnb-base(最流行的JS代码格式规范)

eslint-webpack-plugin(webpack的eslint插件)

eslint-plugin-import(用于在package.json中读取eslintConfig配置项)

配置

eslint-webpack-plugin

const ESLintPlugin = require('eslint-webpack-plugin');plugins: [new ESLintPlugin(options)],

eslintConfig(package.json)

'eslintConfig': {"extends":"airbnb-base"}

Webpack打包图片

file-loader

将用到的图片复制到输出目录,过滤掉不用的图片

npm i file-loader -D

url-loader

file-loder的升级版,如果图片小于配置大小,会转成base64字符串

转成base64字符串后,图片会跟js一起加载(减少图片的请求次数)

npm i url-loader -D

html-loader

将html导出为字符串(负责引入img,从而能被url-loader进行处理)

npmjs.com/package/html-...

html-loader与html-webpack-plugin的冲突

原因:html-webpack-plugin会检查目标文件是否已经有loader处理,如果有其他的loader处理,html-webpack-plugin不在使用loadsh.template去处理ejs语法

解决:html-webpack-plugin中,模板文件的后缀名改为 .ejs(非.html)

Webpack打包字体

字体文件

https://www.iconfont.cn

file-loader

test:/\.(eot|svg|ttf|woff|woff2)$/i,

copy-webpack-plugin

不需要处理的其他文件,可以直接复制到输出目录

clean-webpack-plugin(每次打包之前,先删除历史文件)

资源模块(Assert Modules)

功能

资源模块是一种模块类型,允许使用资源文件,而无需配置额外loader

资源文件:字体,图片,图标,html

不用file-loader,url-loader也能加载图片和文字

Webpack4

raw-loader (将文件导入为字符串)

file-loader (将文件发送到输出目录)

url-loader (将文件发送到输出目录/转为Data URL内联到bundle中)

Webpack5

asset/resource 发送一个单独的文件并导入URL (之前通过file-loader实现)

asset/inline 导出一个资源的data URL (之前通过使用url-loader实现)

asset/source 导出资源的源代码 (之前通过使用raw-loader实现)

asset在导出一个data URL和发送一个单独的文件之间自动选择(url-loader)

Webpack Dev Server

作用:发布web服务,提高开发效率

使用

Webpack4:webpack-dev-serve

Webpack5:webpack serve

npm install webpack-dev-server --save-dev

热更新

Webpack4 hot:true

Webpack5 liveRoad:true(禁用hot)

Target: “web” (热更新只适用于web相关的targets)

Proxy(配置接口代理)

解决webpack-dev-serve下,访问接口的跨域问题

Webpack进阶

Webpack区分环境打包

  1. 通过环境变量区分

Webpack --env.production

Webpack.config.js中判断env

  1. 通过配置文件区分

Webpack.dev.conf.js

Webpack.prod.conf.js

执行打包时,指定配置文件(webpack--config webpack.[dev|prod].conf.js)

Webpack通过环境变量进行打包

命令行中设置环境变量

Webpack 4: webpack --env.production
Webpack 5: webpack --env production

webpack.config.js

读取环境变量 env.production

根据环境变量指定不同的配置

Webpack通过配置文件区分打包

通过配置文件区分环境

Webpack.dev.config.js(mode:development)

Webpack.prod.config.js(mode:production)

Webpack.base.config.js(公共配置)

Webpack-merge 将多个配置合并在一起

Webpack DefinePlugin

DefinePlugin

为配置注入全局变量

开发环境和生产环境的接口地址不同

自定义plugin

Webpack插件是一个具有apply方法的JavaScript对象。apply方法会被webpack compiler调用,并且在整个编译生命周期都可以访问compiler对象

原理:通过在生命周期的钩子中挂载函数,来实现功能扩展

生命周期

生命周期是整个生命过程的关键点

程序:初始化-挂载-渲染-展示-销毁

钩子(生命周期中的函数)

提前在可能增加功能的地方,预设一个函数

自定义loader

loader本质上是一个ESM模块,导出一个函数,在函数中对打包资源进行转换

声明一个读取markdown(.md)文件内容的loader

marked(将markdown语法转成html)

loader-utils(接收loader的配置项)

代码分离

如果把所有代码都打包到一起,可能最终的代码非常大。从而影响到加载时间,很多代码初始是不需要的。可以根据代码使用的紧急程度,将代码分割打包后按需加载。

实现代码分离

  1. 多入口打包:配置entry加载多个入口文件
  2. 提取公用模块:optimization.splitChunks.chunks:all
  3. 动态导入:按需加载|预加载

代码分离----多入口打包

entry(后面写成对象)

{index:'./src/index.js',about:'./src/about.js'}

output.filename(不能写成固定名称,否则报错)、

[name].bundle.js

HtmlWebpackPlugin(不同页面加载割自己的bundle)

Chunks:[‘index’]index.html加载index.bundle.js

Chunks:[‘about’]about.html加载about.bundle.js

代码分离---提取公共模块

多个页面都用到了一个公共文件,每个页面都将公共文件打包一次是不合理的。更好的办法是将公共文件提取出来

Optimization.splitChunks.chunks:all

将公共文件提取出来,单独打包

代码分离---动态导入

懒加载

默认不加载,事件触发后才加载

WebpackChunkName:“加载名称”

预加载

先等待其他资源加载,浏览器空闲时,再加载

WebpackPrefetch:true

缺点:在移动端有兼容性问题

源码映射(Source Map)

一种源代码与构建后代码之间的映射技术

通过 .md文件,将构建后的代码与源代码之间建立映射关系

为什么使用Source Map

问题:构建后的代码,出了问题后不好定位

方案:有了Source Map之后,可以快速定位问题代码

生成Source Map

Devtool:’隐射模式‘

映射模式(devtool的值)

不同映射模式的报错定位效果和打包执行速度不同

webpack4 中,一共有13种不同的映射模式

webpack5 中,一共有26种不同的映射模式

Webpack 5种的命名更新严格

webpack4

选取合适的映射模式

开发环境 (eval-cheap-module-source-map)

生产环境 (none|nosources-source-map)

缓存

Babel缓存

cacheDirectory:true(第二次构建时,会读取之前的缓存)

文件资源缓存

如果代码在缓存期内,代码更新后看不到实时效果

方案:将代码文件名称,设置为哈希名称,名称发生变化,就加载最新的内容

Webpack哈希值

[hash](每次webpack打包生成的hash值)

[chunkhash](不同chunk的hash值不同 同一次打包可能生成不同的chunk)

[contenthash](不同内容的hash值不同,同一个chunk中可能有不同的内容)

模块解析(resolve)

resolve

配置模块解析的规则

alias:配置模块加载的路径别名

Alias:{‘@’:resolve(‘src’)}

extensions:引入模块时,可以省略哪些后缀

extensions:[“.js”,”.json”]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值