Commonjs
requiremodule.exports / exports.xxxES Module
importexport default / export xxx使用 Commonjs 导出一个模块 utils
// test-cli-0174\bin\utils.js
module.exports = function () {
console.log('hello utils');
};主文件中通过 ES Module 的方式引入模块
// test-cli-0174\bin\index.js
#!/usr/bin/env node
import utils from './utils';
utils();运行程序,发现会报错 Cannot use import statement outside a module ,意思就是不让用 import 语法。
那么我们如何让 Node 环境支持 ES Module 呢?
npm i -D webpack webpack-cli主文件使用 require 去调用 webpack 构建后的 core.js
// test-cli-0174\bin\index.js
#!/usr/bin/env node
require('./dist/core');core.js 使用 es module 引入 utils.js
// test-cli-0174\bin\core.js
import utils from './utils';
utils();// webpack.config.js
const path = require('path');
module.exports = {
entry: './bin/core.js',
output: {
path: path.join(__dirname, '/dist'),
filename: 'core.js',
},
mode: 'development',
}; "scripts": {
"build": "webpack",
"dev": "webpack -w"
},npm run build构建完成会出现 dist 目录以及构建后的 core.js
再次运行程序,发现可以正常运行。
可以启动监听状态,当文件发生变化时,自动执行构建过程
npm run dev当我们调用 node 的内置库时,比如 path、fs,webpack 构建会报错,因为 webpack 默认使用 web 环境进行构建,web 环境不存在 node 的内置库,所以我们需要修改 target 属性为 node。
// webpack.config.js
const path = require('path');
module.exports = {
entry: './bin/core.js',
output: {
path: path.join(__dirname, '/dist'),
filename: 'core.js',
},
target: 'node', // 默认是web
};// test-cli-0174\bin\utils.js
import { pathExistsSync } from 'path-exists';
export function exists(p) {
return pathExistsSync(p);
}// test-cli-0174\bin\core.js
import path from 'path';
import { exists } from './utils';
console.log(path.resolve('.'));
console.log(exists(path.resolve('.')));执行程序,没有什么问题了。
安装依赖
npm i -D
babel-loader
@babel/core
@babel/preset-env
@babel/plugin-transform-runtime
@babel/runtime-corejs3配置 webpack
// webpack.config.js
const path = require('path');
module.exports = {
entry: './bin/core.js',
output: {
path: path.join(__dirname, '/dist'),
filename: 'core.js',
},
mode: 'development',
target: 'node', // 默认是web
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|dist)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: [
[
'@babel/plugin-transform-runtime',
{
corejs: 3,
regenerator: true,
useESModules: true,
helpers: true,
},
],
],
},
},
},
],
},
};需要修改文件名的后缀为 .mjs,并且一旦使用 mjs,所有的内容都需要使用 ES Module,不可混用,否则会报错。
// test-cli-0174\bin\index.mjs
#!/usr/bin/env node
import './core.mjs';// test-cli-0174\bin\core.mjs
import path from 'path';
import { exists } from './utils.mjs';
console.log(path.resolve('.'));
console.log(exists(path.resolve('.')));// test-cli-0174\bin\utils.js
import { pathExistsSync } from 'path-exists';
export function exists(p) {
return pathExistsSync(p);
}最后 通过一个指令来执行程序
node --experimental-modules bin/index.mjs
// node14版本之后 不需要加 --experimental-modules 指令也可以
node bin/index.mjs同样能得到结果,没有什么问题。
如果不希望将后缀名改成 .mjs,可以在项目的 package.json 文件中,指定 type 字段为 module。
{
"type": "module"
}一旦设置了以后,该目录里面的 JS 脚本,就被解释用 ES6 模块。