How can I use an es6 import in node? [duplicate]

落花浮王杯 提交于 2019-11-25 22:07:53

问题


I\'m trying to get the hang of es6 imports in node and am trying to use the syntax provided in this example:

Cheatsheet Link: https://hackernoon.com/import-export-default-require-commandjs-javascript-nodejs-es6-vs-cheatsheet-different-tutorial-example-5a321738b50f

I\'m looking through the support table: http://node.green/, but was not able to find what version supports the new import statements (I tried looking for the text import/require) I\'m currently running node 8.1.2 and also believe that since the cheatsheet is referring to .js files it should work with .js files.

As I run the code (taken from cheatsheet\'s 1st example):

import { square, diag } from \'lib\';

I get the error: SyntaxError: Unexpected token import.

Reference to lib I\'m trying to import:

//------ 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));
}

What am I missing and how can I get node to recognize my import statement?


回答1:


Node.js has included experimental support for ES6 support. Read more about here: https://nodejs.org/api/esm.html.

TLDR; Save the file with ES6 modules with .mjs extension and run it like:

node --experimental-modules my-app.mjs

Node.js doesn't support ES6 modules. This blog by James describes the reasons for it. Though you can use Babel to use ES6 modules syntax.




回答2:


You can also use npm package called esm which allows you to use ES6 modules in node. It needs no configuration. With esm you will be able to use export/import in your JS files.

Run the following command on your terminal

yarn add esm 

or

npm install esm

After that, you need to require this package when starting your server with node. For example if your node server runs index.js file, you would use the command

node -r esm index.js

You can also add it in your package.json file like this

{
  "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"
  },

}

Then run this command from the terminal to start your node server

npm start

Check this link for more details




回答3:


Wasted about 3 hours.

I just wanted to use the import and export in js files.

Everyone says not possible. But, as of May 2018, it's possible to use above in plain node.js, without any modules like babel, etc.

Here is a simple way to do it.

Create below files, run and see output for yourself.

Also don't forget to see Explanation below.

myfile.mjs

function myFunc() {
    console.log("Hello from myFunc")
}

export default myFunc;

index.mjs

import myFunc from "./myfile.mjs"  // simply using "./myfile" may not work in all resolvers

myFunc();

run

node  --experimental-modules  index.mjs

output

(node:12020) ExperimentalWarning: The ESM module loader is experimental.

Hello from myFunc

Explanation:

  1. Since it is experimental modules, .js files are named .mjs files
  2. While running you will add --experimental-modules to the node index.mjs
  3. While running with experimental modules in the output you will see: "(node:12020) ExperimentalWarning: The ESM module loader is experimental. "
  4. I have the current release of node js, so if I run node --version, it gives me "v10.3.0", though the LTE/stable/recommended version is 8.11.2 LTS.
  5. Someday in the future, you could use .js instead of .mjs, as the features become stable instead of Experimental.
  6. More on experimental features, see: https://nodejs.org/api/esm.html

Hope that helped.

 




回答4:


Using Node v12.2.0 I can import all standard modules like this:

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'

Versus what I did before:

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

Any module that is an ECMAScript module can be imported without having to use an .mjs extension as long as it has this field in its package.json file:

"type": "module"

So make sure you put such a package.json file in the same folder as the module you're making.

And to import modules not updated with ECMAScript module support you can do like this:

// 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')

And of course, do not forget that this is needed to actually run a script using module imports:

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

And that the parent folder needs this package.json file for that script to not complain about the import syntax:

{
  "type": "module"
}

If the module you want to use has not been updated to support being imported using the import syntax then you have no other choice than using require (but with my solution above that is not a problem).




回答5:


If you are using the modules system on the server side, you do not need to use Babel at all. To use modules in NodeJS ensure that:

  1. Use a version of node that supports the --experimental-modules flag
  2. Your .js files must then be renamed to .mjs

That's it.

However and this is a big however, while your shinny pure ES6 code will run in an environment like NodeJS (at writing 9.5.0) you will still have the craziness of transpilling just to test. Also bear in mind that Ecma has stated that release cycles for Javascript are going to be faster, with newer features delivered on a more regular basis. Whilst this will be no problems for single environments like NodeJS, its a slightly different proposition for browser environments. What is clear is that testing frameworks have a lot to do in catching up. You will still need to probably transpile for testing frameworks. I'd suggest using jest.

Also be aware of bundling frameworks, you will be running into problems there




回答6:


You may try esm.

Here are some introduction: https://www.npmjs.com/package/esm




回答7:


Back to Jonathan002's original question about

"... what version supports the new ES6 import statements?"

based on the article by Dr. Axel Rauschmayer, there is a plan to have it supported by default (without the experimental command line flag) in Node.js 10.x LTS. According to node.js's release plan as it is on 3/29, 2018, it's likely to become available after Apr 2018, while LTS of it will begin on October 2018.




回答8:


solution

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');

below is definition of mixins/index.js

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

that worked just fine inside my node.js CLI app.




回答9:


  "devDependencies": {
    "@babel/core": "^7.2.0",
    "@babel/preset-env": "^7.2.0",
    "@babel/register": "^7.0.0"
  }

.babelrc

{
  "presets": ["@babel/preset-env"]
}

entry point node.js app

require("@babel/register")({})

// Import the rest of our application.
module.exports = require('./index.js')

Link How To Enable ES6 Imports in Node.JS https://timonweb.com/posts/how-to-enable-es6-imports-in-nodejs/




回答10:


Using the .mjs extension (as suggested in the accepted answer) in order to enable ECMAScript modules works, however, with Node.js v12, you can also enable this feature globally in your package.json.

The official docs state:

import statements of .js and extensionless files are treated as ES modules if the nearest parent package.json contains "type": "module".

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

(Of course you still have to provide the flag --experimental-modules when starting your app).




回答11:


I don't know if this will work for your case but I am running an express server with this:

nodemon --inspect ./index.js --exec babel-node --presets es2015,stage-2

This gives me the ability to import and use spread operator even though I'm only using node version 8.

You'll need to install babel-cli, babel-preset-es2015, babel-preset-stage-2 do do what I'm doing.



来源:https://stackoverflow.com/questions/45854169/how-can-i-use-an-es6-import-in-node

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!