我试图在Node.js中获得ES6导入的窍门,并试图使用本示例中提供的语法:

Cheatsheet链接

我正在查看支持表,但我无法找到支持新的导入语句的版本(我尝试寻找文本import/require)。我目前正在运行Node.js 8.1.2,也相信由于备考表引用的是.js文件,它应该与.js文件一起工作。

当我运行代码时(摘自备忘单的第一个例子):

import { square, diag } from 'lib';

我得到了错误:

SyntaxError:意外的令牌导入。

引用库,我试图导入:

//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

我错过了什么,我如何才能让节点识别我的导入语句?


当前回答

你也可以使用名为esm的npm包,它允许你在Node.js中使用ES6模块。它不需要配置。使用esm,您将能够在JavaScript文件中使用导出/导入。

在终端上运行以下命令

yarn add esm

or

npm install esm

之后,在使用node启动服务器时需要使用这个包。例如,如果您的节点服务器运行index.js文件,您将使用该命令

node -r esm index.js

你也可以把它添加到你的包中。这样的Json文件

{
  "name": "My-app",
  "version": "1.0.0",
  "description": "Some Hack",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node -r esm index.js"
  },

}

然后在终端上运行这个命令来启动节点服务器

npm start

查看这个链接了解更多细节。

其他回答

你可以试试esm。

这里有一些介绍:esm

解决方案

https://www.npmjs.com/package/babel-register

// This is to allow ES6 export syntax
// to be properly read and processed by node.js application
require('babel-register')({
  presets: [
    'env',
  ],
});

// After that, any line you add below that has typical ES6 export syntax
// will work just fine

const utils = require('../../utils.js');
const availableMixins = require('../../../src/lib/mixins/index.js');

下面是mixins/index.js文件的定义

export { default as FormValidationMixin } from './form-validation'; // eslint-disable-line import/prefer-default-export

这在我的Node.js CLI应用程序中工作得很好。

使用Node.js v12.2.0,我可以像这样导入所有标准模块:

import * as Http from 'http'
import * as Fs from 'fs'
import * as Path from 'path'
import * as Readline from 'readline'
import * as Os from 'os'

与我之前做的相比:

const
  Http = require('http')
  ,Fs = require('fs')
  ,Path = require('path')
  ,Readline = require('readline')
  ,Os = require('os')

任何ECMAScript模块都可以导入,而不需要使用.mjs扩展名,只要它的包中有这个字段。json文件:

"type": "module"

所以一定要放一个这样的包。Json文件在同一个文件夹的模块,你正在做。

要导入没有更新ECMAScript模块支持的模块,你可以这样做:

// Implement the old require function
import { createRequire } from 'module'
const require = createRequire(import.meta.url)

// Now you can require whatever
const
  WebSocket = require('ws')
  ,Mime = require('mime-types')
  ,Chokidar = require('chokidar')

当然,不要忘记这是使用模块导入实际运行脚本所需要的(在v13.2之后不需要了):

node --experimental-modules my-script-that-use-import.js

父文件夹需要这个包。Json文件,该脚本不抱怨导入语法:

{
  "type": "module"
}

如果您想要使用的模块还没有更新到支持使用import语法导入,那么您除了使用require别无选择(但对于上面的解决方案,这不是问题)。

我还想分享这段代码,它实现了模块中缺少的__filename和__dirname常量:

import {fileURLToPath} from 'url'
import {dirname} from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

使用.mjs扩展名(在已接受的答案中建议)来启用ECMAScript模块。然而,使用Node.js v12,你也可以在你的包中全局启用这个特性。json文件。

官方文件指出:

.js和无扩展文件的import语句被视为ES模块,如果最近的父包。Json包含“type”:“module”。

{
  "type": "module",
  "main": "./src/index.js"
}

(当然,在启动应用程序时,仍然需要提供标记——experimental-modules。)

你也可以使用名为esm的npm包,它允许你在Node.js中使用ES6模块。它不需要配置。使用esm,您将能够在JavaScript文件中使用导出/导入。

在终端上运行以下命令

yarn add esm

or

npm install esm

之后,在使用node启动服务器时需要使用这个包。例如,如果您的节点服务器运行index.js文件,您将使用该命令

node -r esm index.js

你也可以把它添加到你的包中。这样的Json文件

{
  "name": "My-app",
  "version": "1.0.0",
  "description": "Some Hack",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node -r esm index.js"
  },

}

然后在终端上运行这个命令来启动节点服务器

npm start

查看这个链接了解更多细节。