vue,react,webpack,babel 要点总结

掘金大牛:「历时8个月」10万字前端知识体系总结(基础知识篇)

Vue

基本使用

v-html

原始html内容,有xss风险

computed

  • 有缓存,data不变不会重新计算

watch

监听引用类型,使用下面方法深度监听,但是拿不到oldVal

1
2
3
4
5
6
7
8
watch:{
info: {
handler (oldVal, val) {
console.log((oldVal, val)
},
deep: true
}
}

class 写法

1
2
3
4
5
6
7
8
data () {
isblack: true,
isRed: false,

black: "black",
red: "red"
}
:class={black: isblack, red: isRed}

或者

1
:class=[black, red]

style

object 类型,驼峰写法

v-if 和 v-show 区别

v-if 是否渲染,更新不频繁使用

v-show 是通过 css 的 display 控制显示与隐藏,频繁切换使用

v-for

  • 也可以遍历对象
  • key,不能乱写,尽量不用index,不用random
  • v-for 优先级比v-if

事件

event参数,自定义参数
  • 没有参数,直接可以获取
  • 有参数,用$event
  • event是原生对象
事件修饰符,按键修饰符
1
2
@click.stop.prevent
@click.ctrl.exact
!(观察)事件被绑定到哪里

event.target的值表明事件是挂在当前元素上的

表单

v-model

v-model.trim

v-model.lazy

v-model.number

组件使用

props

简写

1
props:['list']

复杂写法,常用,可以定义类型和默认值

1
2
3
4
5
6
props: {
type: Array,
default:{
return []
}
}

$emit

父组件

1
<Input @add="clickhandler"/>

子组件

1
2
3
4
5
methods:{
addTitle() {
this.$emit('add', title)
}
}

组件通信 - 自定义事件(兄弟组件通信)

vue 具有自定义事件能力 $on、$off、$emit

组件卸载时,解除事件绑定,销毁子组件,定时器等

组件生命周期

  • 挂载阶段
  • 更新阶段
  • 销毁阶段

单个组件

created:vue实例化完成

mounted:渲染完成

父子组件

组件实例创建: 先父后子

组件渲染: 先子后父【子组件渲染完,才能挂载】

高级特性

自定义 v-model

父组件中

1
<CunstomVModal v-model={name}>

子组件中 CunstomVModal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<input type="text" :value="txt" @input="$emit('chage', $event.target.value)"
</template>
<script>
export default {
model:{
prop: 'txt',
event:'chage'
},
props:{
txt: String,
default () {
return ''
}
}
}
</script>

$nextTick、refs

  • vue 是异步渲染
  • data 改变之后,dom不会like渲染
  • $nextTick 会在dom渲染之后被处罚,以获取最新的dom节点

slot

  • 基本使用
  • 作用于插槽
  • 具名插槽

动态组件

  • :is=”component-name”
  • 需要根据数据,动态渲染的场景。即组件类型不确定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<component :is="compName">
</template>
<script>
import myComp from './myComp'
components:{
myComp
},
data () {
return {
compName: 'myComp'
}
}

</script>

异步组件

  • import()
  • 按需加载,异步加载大组件
1
2
3
4
5
export default {
components:{
Demo: () => import('./ImportDemo')
}
}

keep-alive

  • 缓存组件
  • 频繁切换,不需要重复渲染
  • vue常见性能优化
1
2
3
4
5
6
7
// 每个组件只渲染一次,且不会销毁。
// 简单的用v-show就行,稍微复杂的用keep-alive
<keep-alive>
<A v-if="a"></A>
<B v-if="b"></B>
<C v-if="c"></C>
</keep-alive>

mixin

  • 多个组件有相同的逻辑,抽离出来
  • mixin并不是完美的解决方案,会有一些问题
  • vue 3 提出的 composition API 旨在解决这些问题

问题
  • 变量来源不明确,不利于阅读
  • 多个mixin可能会造成命名冲突
  • mixin和组件可能会出现多对多的关系,复杂度较高

1
2
3
4
5
6
7
8
9
<sript>
import Mixin from './mixin'
export default {
mixins: [Mixin],
data () {
return {}
}
}
</sript>

vuex 使用

  • 基本概念、基本使用、API
  • state的数据结构设计
vuex基本概念
  • state
  • gettters
  • action
  • mutation
用于vue组件
  • dispatch
  • commit
  • mapstate
  • mapGetters
  • mapActions
  • mapMutations

vue-router

  • 路由模式:
    • hash
      • window.onhashchange
      • 会出发网页跳转,
      • 可前进后退,
      • 不会提交到server端,强制刷新也不会
      • 可刷新
    • H5 history
      • history.pushState
      • window.onpopstate
      • 不可刷新(需要后端支持)
  • 路由配置:
    • 动态路由 {path: ‘/user/:id?’, component: User}
    • 懒加载 {path: ‘/user/:id?’, component: () => import(‘./user’)}

Vue原理

如何里面MVVM

  • 很久以前的视图
    • asp jsp php 已经有组件化了
    • 传统组件,只是静态渲染,更新依赖于操作dom
  • 数据驱动视图(vue MVVM,react setState)

vue 响应式

  • 组件data的数据一旦变化,立刻出发视图更新
  • 核心API - Object.defineProperty
    • get
    • set
  • Object.defineProperty 的一些缺点 (Vue3.0 使用 Proxy)
  • proxy 兼容性不太好,且无法 polyfill
Object.defineProperty 缺点
  • 深度监听,需要递归到底,一次性计算量大
  • 新增,删除 无法监听,需要用 Vue.set 和 Vue.delete
  • 无法监听数组,需要专门处理
Proxy 实现响应式
  • 基本使用
  • Reflect
  • 实现响应式
  • 对比 defineProperty 提高性能
    • set第一层属性的时候,触发set
    • set第二层属性的时候触发第一层属性的get
    • 所以在get的时候,返回一个 新的proxy对象即可 深度监听,而且是惰性监听
    • 所以性能比defineProperty好

虚拟DOM 和 diff

  • DOM操作非常耗性能,js是执行非常快的
  • vue和react是数据驱动视图
vdom

用js模拟dom结构,计算出最小的变更,操作dom

snabbdom

h函数,返回vnode(js)
patch(container, vnode) 初次渲染
patch(oldVnode, newVnode) 更新,新旧vnode都有children,那么updateChildren
patch(oldVnode, null) 销毁清空

diff
  • 只比较同一层级,不跨级比较
  • tag不相同,直接删掉重建,不再深度比较
  • tag和key都相同,则认为是相同节点,不再深度比较
模板编译
  • vue将模板编译为render函数
  • 执行render函数生成vnode,patch
  • 触发响应式,监听data属性getter setter
  • with语法
  • vue组件可以用render代替template
初次渲染过程
  • 解析为render函数
  • 触发响应式,监听data属性getter setter
  • 执行render函数,生成vnode,patch
更新过程
  • 修改data,触发setter,(此前在getter中已被监听)
  • 重新执行render函数,生成newVnode
  • patch(oldVnode, newVnode)
组件异步渲染
  • $nextTick
  • 汇总data修改,一次性更新视图
  • 减少dom操作次数,提高性能

Vue3

新功能
  • createApp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // vue2
    const app = new Vue({})
    Vue.use()
    Vue.mixin()
    Vue.component()
    Vue.directive()
    // vue3
    const app = Vue.createApp({})
    app.use()
    app.mixin()
    app.component()
    app.directive()
  • emits属性

    1
    emits: ['onClickhandler'] // 建议 onXxx
  • 生命周期

    • beforeDestroy 改为 beforeUnmount
    • destroyed 改为 unmounted
  • 多事件处理, @click=”one($event),two($event)”

  • Fragment, 模板不需要包在一个根组件中了,template下面可以写多个标签

  • 移除.sync改为v-model参数

  • 异步组件的引用方式, defindAsyncComponent

  • 移除filter,如:v-if=”boolA | boolB”

  • Teleport,

  • Suspense

1
2
3
4
5
6
7
8
9
10
11
12
<Suspense>
<template>
<Test1/> <!-- 是一个异步组件 -->
</template>
<!-- 具名插槽
即:Suspense 组件内部,有两个slot,
其中一个具名为 fallback
-->
<tempalte #fallback>
Loading...
</tempalte>
</Suspense>
  • Composition API
    • reactive
    • ref toRef toRefs
    • readonly
    • computed
    • watch watchEffect
    • 钩子函数生命周期
原理
  • proxy 实现响应式
    • 对值类型无能为力,所以要用 ref
  • 编译优化
    • PatchFlag 静态标记
    • hoistStatic 静态提升
    • cacheHandler 缓存事件
    • SSR 优化
    • Tree-shaking 优化
Vue3 比 vue2 优势
  • 性能更好
  • 体积更小
  • 更好的ts支持
  • 更好的代码组织
  • 更好的逻辑抽离
  • 更多的新功能
生命周期
  • beforeDestroy 改为 beforeUnmount
  • destroyed 改为 unmounted
  • 其他沿用vue2的生命周期
  • setup等于 beforeCreate 和 created
1
2
3
4
5
6
7
8
9
10
11
import { onBeforeMount } from 'vue'

export default {
<!-- 其他代码 -->
setup () {
onBeforeMount(() => {
console.log('onBeforeMount')
})
}
<!-- 其他代码 -->
}
Composition API 对比 Options API
  • 更好的代码组织
  • 更好的逻辑复用(options api 分散于生命周期中,代码越多越明显)
  • 更好的类型推导(直接this.a 和 this.fn,不利于类型判断 )
  • 不建议共用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export default {
data () {
return {
a: 10
}
},
methods: {
fn () {
const a = this.a
}
},
mounted: {
this.fn()
}
}
ref toRef toRefs
  • toRef 将一个响应式对象中的某个属性变为ref
  • toRefs 将一个响应式对象变为普通对象,这个普通对象的每个属性变为ref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<template>
<div>{{name}}{{ageRef}}</div>
<div ref="eleRef">我是文字</div>
</template>

<script>
import { ref, toRef, toRefs, reactive, onMounted } from 'vue'

export default {
name: 'Ref',
setup() {
const eleRef = ref(null)
const ageRef = ref(20)
// 两者保持引用关系↓
// 不能返回解构的state,会丢失响应式
const state = reactive({
name: '张三'
})
const nameRef = toRef(state, 'name')
nameRef.value = '李四' // state中的name也会改变
state.name = '王五' // nameRef的值也会改变
// 两者保持引用关系 ↑
ageRef.value = 30
onMounted(() => {
console.log(eleRef.value.innerHTML)
})

// const stateRefs = toRefs(state)
// const {name: nameRef} = stateRefs
// return stateRefs // toRefs的返回

// 其他返回
return {
ageRef,
eleRef
}
}
}
</script>

为什么要用 Ref
  • 返回 值类型,会丢失响应式
  • 如在setup、computed、合成函数,都有可能返回 值类型
  • vue如果不定义ref。用户将自造ref,反而更混乱
为什么要.value
  • ref 是个对象(不丢失响应式),value存储值
  • 通过.value属性的get和set实现响应式
  • 用于模板、reactive时,(vue可以自己控制)不需要.value,其他情况都需要
Composition API 实现逻辑复用
  • 抽离逻辑代码到一个函数
  • 函数命名约定为 useXxx 格式
  • setup中引用 useXxx 函数
Proxy 实现响应式
  • 基本使用
  • Reflect
  • 实现响应式
  • 对比 defineProperty 提高性能
    • set第一层属性的时候,触发set
    • set第二层属性的时候触发第一层属性的get
    • 所以在get的时候,返回一个 新的proxy对象即可 深度监听,而且是惰性监听
    • 所以性能比defineProperty好
watch 和 watchEffect 的区别
  • 两者都可以监听data属性变化
  • watch 需要明确监听哪个属性
  • watchEffect会根据其中的属性,自动监听其变化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// watch 默认不会立即执行
// 监听ref
watch(nameRef, (newVal, oldVal) => {}, [options])
// 监听响应式
watch(() => state.name, (newState, oldState) => {}, [options])

watchEffect(() => {
// 初始化就会执行一次,收集监听的数据
console.log('watchEffect')
})
watchEffect(() => {
// 写了 state.name 就监听, 不写的不会监听
console.log(state.name)
})
setup中如何获取组件实例
  • 在setup 和 Composition API 中没有this
  • 可通过 getCurrentInstance 获取当前实例
  • 若使用 options API 可照常使用 this
vue3 为何比 vue2 快
  • Proxy 响应式
  • PatchFlag // 标记节点类型
  • hoistStatic // 缓存静态节点,多个节点合并
  • cacheHandler //
  • SSR 优化
  • tree-shaking
PatchFlag
  • 编译模板时,动态节点做标记
  • 标记分为不同类型,如 TEXT PROPS
  • diff算法时,可以区分静态节点,以及不同类型的节点
hoistStatic
  • 将静态节点的定义,提升到父作用域,缓存起来
  • 多个相邻的静态节点,会被合并起来
  • 典型的拿空间换时间的优化策略
cacheHandler
  • 将事件缓存起来
vite - ES6 module

React

基本使用

setState

  • 不可变值,为了SCU
  • 可能异步可能同步
  • 可能会被合并
是同步还是异步
  • 直接使用是异步的
  • 在setTimeout或者自定义的dom事件中是同步的
何时会合并
  • 对象形式,会被合并
  • 函数形式,不会合并
1
this.setState((state, props) => {})
  • 直接修改state的值,影响性能

事件为何要bind this

  • class生成的实例中,this是undefined

Reaact 高级特性

  • 函数组件
  • 非受控组件
  • Portals ReactDOM.createPortals()
  • context
  • 异步组件,import() React.lazy React.Suspense
  • 性能优化,SCU 核心问题是 不可变值
  • 高阶组件HOC
  • render props
jsx 本质是什么
  • React.createElement 函数,执行返回 vnode
事件合成机制
  • div 冒泡至 document,合成统一的react event,dispatchEvent事件派发交由对应的处理器执行
  • 更好的兼容性和跨平台
  • 挂载到根节点,减少内存消耗,避免频繁解绑
  • 方便统一管理(如事务机制)
transaction 事务机制

Transaction类的主要作用使用提供的包装(Wrapper)来包装一个函数。
Transaction会接受一个方法 func,和一组Wrapper。Transaction会在func执行之前,执行一组Wrapper中的initialize方法。而后执行func方法,在func方法执行完了之后,执行Wrapper提供的所有close方法。

fiber
  • props state
  • render 生成 vnode
  • patch(ele, vnode)
    • reconciliation 执行diff算法,纯js计算
      • 进行任务拆分
      • DOM需要渲染时暂停,空闲时恢复
      • window.requestIdleCallback
    • commit 阶段,将diff结果渲染到dom中
react 性能优化
  • 渲染列表key
  • 及时销毁事件
  • 合理使用异步组件
  • 减少 bind 次数
  • 合理使用 scu pure memo
  • 合理使用 immutablejs
  • 打包webpack优化
  • 前端通用优化 图片懒加载等
  • SSR
React 和 Vue 区别

1、共同

  • 支持组件化
  • 数据驱动视图
  • vdom操作dom

2、不同

  • React 使用 jsx 拥抱js(文件都是.js结尾),Vue使用模板拥抱html(文件是.vue结尾)
  • React 函数式编程,Vue 声明式编程
  • React 更多需要自力更生,Vue 把想要的都给你

Webpack

升级webpack5 级周边插件后。需要做的调整

  • package.json的dev-server命令改了,
    • 4: “dev”:”webpack-dev-server –config build/webpack.dev.js”
    • 5: “dev”:”webpack serve –config build/webpack.dev.js”
  • webpack-merge
    • 4: const { smart } = require(‘webpack-merge’)
    • 5: const { merge } = require(‘webpack-merge’)
  • CleanWebpackplugin
    • 4: const CleanWebpackplugin = require(‘clean-webpack-plugin’)
    • 5: const { CleanWebpackplugin } = require(‘clean-webpack-plugin’)
  • modules.rules
    • 4: loader: [‘xxx-loader’]
    • 5: use: [‘xxx-loader’]
  • filename hash h小写
    • 4: filename: ‘bundle.[contentHash:8].js’
    • 5: filename: ‘bundle.[contenthash:8].js’

基本配置

  • 拆分配置 和 merge

  • 启动本地服务 webpack-dev-server

  • 处理 ES6

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    modules.exports = {
    entry: path.join(srcPath, 'index'),
    modules: {
    rules: [
    {
    test: /\.js$/,
    loader: ['babel-loader'],
    include: srcPath,
    exclude: /node_modules/
    }
    ]
    }
    }
    1
    2
    3
    4
    {
    "presets": ["@babel/preset-env"],
    "plugins": []
    }
  • 处理样式

  • 处理图片

    • file-loader 将图片变为url形式
    • url-loader 将图片变为base64形式,减少http请求,很小没必要再进行http请求
  • 模块化

高级配置

多入口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
entry: {
index: path.join(srcPath, 'index.js'),
other: path.join(srcPath, 'other.js'),
},
output: {
filename: '[name].[contentHash:8].js',
path: distPath
}
plugins: [
new HtmlWebpackPlugin({
template: path.join(srcPath, 'index.html'),
filename: 'index.html',
chunks: ['index'] // 要引入什么js文件
}),
new HtmlWebpackPlugin({
template: path.join(srcPath, 'other.html'),
filename: 'other.html',
chunks: ['other']
})
]

抽离css文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
coonst MiniCssExtracctplugin = require('mini-css-extract-plugin')
const TerserJSPlugin = require('terser-webpack-plugin')
const OptimizeCssAssetsplugin = require('optimize-css-assets-webpack-plugin')

module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: [
MiniCssExtracctplugin.loader,
'css-loader',
'postcss-loader'
]
}
]
},
plugins: [
new MiniCssExtracctplugin({
filename: 'css/main.[contentHash:8].css'
})
],
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCssAssetsplugin({})]
}
}

压缩 optimization

1
2
3
4
5
6
7
8
9
const TerserJSPlugin = require('terser-webpack-plugin')
const OptimizeCssAssetsplugin = require('optimize-css-assets-webpack-plugin')

module.exports = {
<!-- 其他配置 -->
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCssAssetsplugin({})]
}
}

抽离公共代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
module.exports = {
<!-- 其他配置 -->
optimization: {
minimizer: [],
splitChunks: {
// initial 不处理异步
// async 只处理异步
// all 全部
chunks: 'all',
cacheGroups: {
// 引用关系 关联 HtmlWebpackPlugin chunks 配置
// 第三方模块
vendor: {
name: 'vendor', // chunk 名称
priority: 1, // 权限更高,有限抽离,重要!
test: /node_modules/, //
minSize: 0, // 大小限制,实际开发不要写0
minChunks: 1, // 最少复用过几次
},
vendor: {
name: 'common', // chunk 名称
priority: 0, // 权限更高,有限抽离,重要!
minSize: 0, // 大小限制
minChunks: 2, // 最少复用过几次
}
}
}
}
}

异步加载

1
2
3
4
// 定义 chunk
import('./dynamic-data.js').then(res => {
console.log(res.default.message)
})

module chunk bundle 区别

  • module:就是写的代码,只要可以引入的都是module
  • chunk:多模块合并成的,比如:index.js以及它引入的其他文件的集合
  • bundle:最终的输出文件

性能优化,构建速度

  • 优化babel-loader
  • IgnorePlugin
  • noParse
  • happypack
  • parallelUglifyPlugin
  • 自动刷新
  • 热更新
  • DllPlugin

优化babel-loader

1
2
3
4
5
6
7
{
test: /\.js$/,
use: ['babel-loader?cacheDirectory'], // 开启缓存
include: path.resolve(__dirname, 'src'), // 明确范围
// 排除范围, 两者选一即可
// exclude: path.resolve(__dirname, 'node_modules')
}

IgnorePlugin,直接不引入,代码中没有

1
2
3
4
// 不引入所有语言包
new webpack.IgnorePlugin(/\.\/locale/, /moment/)
// 手动引入中文
moment.locale('zh-cn')

noParse,引入,但不打包

1
2
3
4
5
6
7
8
9
modules.exports={
module: {
noParse: [/react\.min\.js/],
rules: [
{}
]
}
}

happyPack 多线程打包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const HappyPack = require('happypack')

module.exports = {
modules: {
rules: [
{
test: /\.js$/,
use: ['happypack/loader?id=babel'],
include: srcPath
}
]
},
plugins: [
new Happypack({
id: 'babel',
loaders: ['babel-loader?cacheDirectory']
})
]
}

ParallelUglifyPlugin 多进程压缩js

new ParallelUglifyPlugin({
uglifyJS: {
// 还是使用 uglifyjs 压缩,只是开启了多进程
output: {
beautify: false, // 最紧凑的输出
comments: false // 删除所有注释
},
compress: {
// 删除所有 console 语句,可兼容ie
drop_console: true,
}
}
})

自动刷新

1
2
3
4
5
6
7
8
9
10
module.exports = {
// 开启之后, webpack-dev-server 会自动开启刷新浏览器
watch: true, // 默认false
watchOptions: {
ignored: /node_modules/, // 忽略
aggregateTimeout: 300, // 监听变化后等300ms再执行,防止太快
poll: 1000 // 每隔1000ms 询问一次
}

}

DllPlugin

  • 前端框架如 vue react , 体积大,构建慢
  • 较稳定,不常升级版本
  • 同一个版本只构建一次即可,不用每次都重新构建
  • webpack 内置
  • 打包出dll文件
  • DllReferencePlugin - 使用dll文件

1、打包dll配置 webpacl.dll.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module.exports = {
mode: 'development',

entry: {
// 把 React 相关模块的放到一个单独的动态链接库
react: ['react', 'react-dom']
},
output: {
filename: '[name].dll.js',
path: distPath,
library: '_dll_[name]'
},
plugins: [
new DllPlugin({
name: '_dll_[name]',
path: path.join(distPath, '[name].mainfest.json'),
})
]
}

2、修改index.html模板

添加

3、配置webpack.dev.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

moduls: {

rules: [
{
test: /\.js$/,
loader: ['babel-loader'],
include: srcPath,
exclude: /node_modules/ // 使用dll,所以不需要转换了
}
]

},

plugins: [

new DllReferencePlugin({
mainfest: require(path.join(distPath, 'react.mainfest.json'))
})

]

webpack 优化构建速度 (可用于生产环境)

  • 优化 babel-loader
  • IgnorePlugin
  • noParse
  • happyPack
  • parellelUglifyPlugin

webpack 优化构建速度 (不可用于生产环境)

  • 自动刷新
  • 热更新
  • DllPlugin

webpack性能优化 - 产出代码

  • 体积更小

  • 合理分包,不重复引用

  • 速度更快,内损使用更少

  • 小图片base64编码

  • bundle + hash

  • 懒加载 import 语法

  • 提取公共代码 splitChunks

  • IgnorePlugin

  • cdn加速

  • 使用 production

  • Scope Hosting 改变打包作用域

使用 production
  • 自动开启代码压缩
  • Vue React 等会自动删除调试代码(如开发环境的warning)
  • 启动 Tree-Shaking
Scope Hosting
  • 代码体积更小
  • 创建函数作用域更少
  • 代码可读性更好
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const ModuleConcatenationPlugin = require('webpack/lib/optmize/ModuleConcatenationPlugin')

module.exports = {

resolve: {
// 针对npm中的第三方模块有限采用 jsnext:main 中指向的es6 模块化语法的文件
mainFields: ['jsnext:main', 'browser', 'main']
},
plugins: [
// 开启 Scope Hosting
new ModuleConcatenationPlugin()
]
}

babel

  • 环境搭建 , 基本配置
    • .babelrc 配置
    • presets 和 plugins
  • babel-polyfill
  • babel-runtime
1
2
3
4
5
6
7
8
9
10
11
12
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltins": "usage", // 按需引入
"corejs": 3 // 版本3
}
]
],
plugins: []
}

babel-polyfill

  • babel 7.4 之后弃用 babel-polyfill
  • 推荐直接使用 core-js 和 regenerator

babel-polyfill 问题

  • 污染全局环境,使用babel-runtime解决

。babelrc中

1
2
3
4
5
6
7
8
9
10
11
12
13
plugins: [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": 3,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]