ES Modules
ESM通过script标签中加入type=module属性定义
ESM的特性
- ESM自动采用严格模式,忽略use strict
- 每一个ESM都是运行在自己独立私有的作用域当中
- ESM通过CORS的方式请求外部js模块
- ESM的script标签会延迟执行脚本
import * as obj from './module.js'
这句话的意思是将module.js文件的所有导出属性拿到,并且赋值给obj这个对象
动态加载模块:
import ('./module.js').then(function (module) {
这里的参数就是模块内导出的内容,因为模块是异步加载的
})
- 在Comment.js模块不能通过require载入ESM模块
- ESM模块可以载入Comment.js模块
- Comment.js始终只会导出一个默认成员
- 注意import不是解构导出对象
在comment.js中 __filename是当前文件的绝对路径
__dirname当前文件所在目录
如果想让js文件都是以ESM形式的,在package.json中加入type: 'module'
即可
webpack打包
webpack支持零配置打包,按照约定就是将src/index.js打包至dist/main.js中
webpack常用配置:
- entry: 入口文件
- output
output: {
filename: '',//输出文件名
path: '',//输出文件的目录(绝对路径) 所以可以用path.join(__dirname, 'dist')
publicPath: 'dist/', webpack打包默认所有的文件都在网站根目录下,publicPath可以告诉webpack打包后的文件在网站的哪个文件下
}
- loader加载器,用来转换其他文件编译打包,webpack内置默认的加载器是处理js的,如果要处理其他类型的文件则需要引入不同的加载器 ↓例子:css-loader
//module(模块)这些选项决定了如何处理项目中的不同类型的模块
module: {
//创建模块时,匹配请求的规则数组。这些规则能够修改模块的创建方式。这些规则能够对模块(module)应用 loader,或者修改解析器(parser)。
rules: [
{
test: /.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'] //@babel/preset-env已经包含了es6的全部最新特性
}
}
},
{
test: /\.vue$/,
use: {
loader: 'vue-loader'
}
},
{
test: /.css$/, //test为正则表达式,用来匹配打包时所遇到的文件路径
use: [
'style-loader',
'css-loader'
],//用来指定匹配到的文件所用到的loader,注意如果是多个loader那么执行顺序是从后往前执行
},
{
test: /.png$/,
use: {
loader: 'url-loader',
options: {
limit: 10 * 1024 //10kb
}
}
}
]
}
光有css-loader还不够,需要通过style-loader将css-loader转化之后的样式通过style标签加载到元素上。
url-loader是将文件转化成data-url的形式,类似于图片转化成base64,但是只适合于小文件转化,因为减少了url的请求次数,大文件单独提取存放,提高加载速度。
关于babel-loader,由于babel只是一个平台,如果要对js文件进行转换的话,需要配置一些babel的插件
常用的loader加载器有三种
- 编译转换类
- 文件操作类
- 代码检查类
- Plugin解决其他自动化工作
常见的plugin插件有:
clean-webpack-plugin
:清除dist包下的内容
html-webpack-plugin
:将html打包生成到dist文件下
copy-webpack-plugin
: 拷贝文件和文件夹
webpack-dev-server
: 启动时会自动打包webpack,并且起一个http server,启动过后,会自动监听文件变化,文件有了变化之后会自动打包更新,但是打包过后的文件并不会存放在磁盘当中,而是存放在内存当中,这样就减少了磁盘读写提高了效率 - devServer
只要被webpack打包正常输出的文件都可以被访问,但是如果其他静态资源也需要被开发服务器访问的话,就需要额外的去告诉webpack的devServer。
还有一点就是,一般开发的时候地址都是localhost,请求api的时候容易跨域,所以需要一个代理服务器转发一下
// 开发环境本地启动的服务配置
devServer: {
historyApiFallback: true, // 当找不到路径的时候,默认加载index.html文件
hot: true,
contentBase: false, // 告诉服务器从哪里提供内容,指定额外的静态资源路径。只有在你想要提供静态文件时才需要
compress: true, // 一切服务都启用gzip 压缩:
port: "8080", // 指定端口号
publicPath: "/", // 访问资源加前缀
proxy: {
// 接口请求代理
},
}
- devtool
用来配置开发过程中的辅助工具,与sourceMap配置相关的功能属性。
sourceMap解决了源代码与编译后代码格式不一样的调试问题,可以在开发者工具里的source调试查看 - devServer
可以配置热更新HMR。
webpack中的HMR需要手动处理热替换的逻辑
const webpack = require('webpack')
derServer: {
//hot: true,
hotOnly: true, // 如果使用hot:true,那么热替换的过程中如果热替换的函数有错误,那么会导致页面重新刷新,这样热替换中的错误控制台就看不见了,所以使用hotOnly让报错不会自动刷新页面,就能看见报错了
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
对于某个文件的热替换可以使用module.hot.accept(文件路径,热处理函数)
- optimization集中去配置webpack的一些优化功能
例如:Tree-shaking,它的前提是使用了ESMudles
optimization: {
usedExports: true,//只导出那些外部使用了的成员,相当于标记了枯树叶
minimize: true, //负责摇掉那些枯树叶,即没用到的代码
concatenateModules: true,//尽可能将所有模块合并都输出到一个函数中去,提升运行效率减少代码体积
sideEffects: true,//开启sideEffects功能,但是这里要确保代码中能识别有用的副作用
}
//注意sideEffects开启之后需要在package.json中配置“sideEffects: fasle”表示没有副作用
webpack api
命令行:
–mode 有三种模式,默认是production,none模式是最原始的打包方式,mode属性也可以直接在webpack中配置。
webpack多入口打包
entry值为对象,且对象的属性为入口名称
entry: {
index: './index.js',
app: './app.js'
},
output: {
filename: '[name].bundle.js',//多个输出,所以用[name]区别每个输出文件名
}
css样式按需加载
所用插件:mini-css-extract-plugin,会将css单独提取到一个css文件之中
在plugin中引用new MiniCssExtractPlugin()
,由于这个插件是将样式用link方式引入的,所以在modules中配置css的时候,可以不用style-loader,而用MiniCssExtractPlugin.loader
打包之后压缩样式文件所用到的插件为optimize-css-assets-webpack-plugin
,但是OptimizeCssAssetsWebpackPlugin插件建议放在optimization
中的minimizer
数组中,因为如果放在plugins
中,那么不管是开发环境还是生产环境都会执行,但是代码压缩建议都放在minimizer
中,因为这样webpack打包到生产环境中的时候会自动开启minimizer,那样就会去压缩代码,而开发环境无需压缩。
如果webpack中一旦配置了minimizer,那么webpack会只执行minimizer中的压缩插件,所以js代码的压缩也需要放在minimizer中,js压缩插件为
terser-webpack-plugin
输出文件名Hash值
文件设置Hash名是为了让静态资源改变的时候能够知道并且重新请求,不然缓存无法分辨文件是否更新
其他打包工具:Rollup
Rollup其实是一款ESM打包器
可以在项目根目录创建一个rollup.config.js的配置文件
commonJs模块可以用rollup-plugin-commonjs
插件
优点:
- 输出结果更加扁平
- 自动移除未引用代码
- 打包结果依然可读
缺点:
- 加载非ESM的第三方模块比较复杂
- 模块最终都被打包到一个函数中,无法实现HMR(模块热开发)
- 浏览器环境中,代码拆分依赖AMD库
如果正在开发类/库,建议使用rollup
ESLint
eslint --init
快速创建eslint配置文件.eslintrc.js
.eslintrc.js文件中:
env:标志文件运行环境
extends:继承一些共享的配置
parserOptions:语法解析器相关配置
rules:配置每个校验规则的开启或者关闭
如果开发中有的代码必须要违反一些校验规则,那么可以使用eslint注释的方式去规避这个代码。// eslint-disable-line 后面跟上具体校验规则名称
配合webpack
eslint-loader
StyleLint
css代码检测工具
git hooks
通过git hooks在代码提交前强制lint
git hooks也成为git钩子,每个钩子都对应一个任务。
通过shell脚本可以编写钩子任务触发时要执行的操作。
Husky可以实现git hooks的使用需求
//package.json文件
"husky": {
"hooks": {
"pre-commit": "npm run precommit"
}
}
lint-staged
//package.json文件
"run": {
"precommit": "lint-staged"
},
"lint-staged": {
"*.js": [
"eslint",
"git add"
]
}