一、CommonJs
导出
- module.exports
module.exports={
name:’zs’,
age:18
}
module.exports.sex = null
- exports (省略module,直接导出)
exports.name = "蛙人"
exports.sex = "male"
导入
- require
// index.js
module.exports.name = "蛙人"
module.exports.age = 24
let data = require("./index.js")
console.log(data) // { name: "蛙人", age: 24 }
二、ES Module
导出
- export (单个导出)
- export default(默认导出)
导入
- imort (只能放在文件顶部,不能动态加载语句)
// index.js
import {isEmpty as isObjectEmpty } from ‘../utils’
import {CONSTANTS as PROJECT_CONSTANTS, BAAS} from ‘../config’
export const PROJECT_CONFIG = {
…PROJECT_CONSTANTS,
FUNCTION: BAAS.CLOUD_FUNCTION
}
三、CommonJs和Es Module的区别
CommonJs
-
CommonJS 模块是 Node.js 专用的,与 ES6 模块不兼容。
-
CommonJS 模块使用 require()和 module.exports
-
CommonJs 可以动态 require 加载语句,代码发生在运行时
-
CommonJs 混合导出,还是一种语法,只不过不用声明前面对象而已,当我导出引用对象时之前的导出就被覆盖了
-
CommonJs 导出值是拷贝,可以修改导出的值,这在代码出错时,不好排查引起变量污染
Es Module
-
ES6模块化在浏览器和 node.js 中都可以用
-
ES6 模块使用 import 和 export
-
Es Module 是静态的,不可以动态加载语句,只能声明在该文件的最顶部,代码发生在编译时
-
Es Module 混合导出,单个导出,默认导出,完全互不影响
-
Es Module 导出是引用值之前都存在映射关系,并且值都是可读的,不能修改
在 node.js 使用模块化,需要将 CommonJS 脚本的后缀名都改成 .cjs ,ES6 模块采用 .mjs 后缀文件名。
或者修改 package.son 里面的文件,type 字段为 module 或 commonjs。
四、Tree Shaking
前端中的 Tree-shaking 可以理解为通过工具"摇"我们的JS文件,将其中用不到的代码"摇"掉,是一个性能优化的范畴。
具体来说,在 webpack 项目中,有一个入口文件,相当于一棵树的主干,入口文件有很多依赖的模块,相当于树枝。实际情况中,虽然依赖了某个模块,但其实只使用其中的某些功能。通过 Tree-shaking,将没有使用的模块摇掉,这样来达到删除无用代码的目的。
开发环境:webpack.config.js 文件中添加 optimization 选项。
生产模式:不用配置下面的属性(默认)
optimization: PROD
? {
runtimeChunk: 'single',
chunkIds: 'deterministic',
moduleIds: 'deterministic',
minimizer: [
new TerserPlugin(terserPluginConfig),
new CssMinimizerPlugin({test: /\.css$/}),
],
splitChunks: splitChunksConfig,
}
: undefined,
package.json文件中添加 sideEffects 选项
"sideEffects": false, //对所有的模块都进行Tree Shaking
如果需要对某个模块不进行Tree Shaking
"sideEffects": ["@babel/poly-fill"], //该模块不进行Tree Shaking
为什么某些引入模块不希望进行Tree Shaking呢?
下面引入的style.css模块,如果也使用Tree shaking,由于css文件没有导出任何模块,那么就有可能在打包的时候该引入模块就被摇晃掉了,导致bug。
在 package.json 中进行配置,即匹配到的任何css文件都不进行Tree Shaking
{
"name":"lesson",
"sideEffects":[*.css]
}
Tree Shaking只支持ES模块的使用,不支持require这种动态引入模块的方式。而ESM的 import 引入是静态引入,commonjs 的require引入 是动态引入。
ES6 module 特点:只能作为模块顶层的语句出现import 的模块名只能是字符串常量import binding 是 immutable的ES6模块依赖关系是确定的,和运行时的状态无关,可以进行可靠的静态分析,这就是tree-shaking的基础。
所谓静态分析就是不执行代码,从字面量上对代码进行分析,ES6之前的模块化,比如我们可以动态require一个模块,只有执行后才知道引用的什么模块,这个就不能通过静态分析去做优化。
这是 ES6 modules 在设计时的一个重要考量,也是为什么没有直接采用 CommonJS,正是基于这个基础上,才使得 tree-shaking 成为可能,这也是为什么 rollup 和 webpack 2 都要用 ES6 module syntax 才能 tree-shaking。
作者:百度外卖大前端技术团
链接:https://juejin.cn/post/6844903544756109319
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。