问题
I've got an ApolloServer project that's giving me trouble, so I thought I might update it and ran into issues when using the latest Babel. My "index.js" is:
require('dotenv').config()
import {startServer} from './server'
startServer()
And when I run it I get the error "SyntaxError: Cannot use import statement outside a module". First I tried doing things to convince TPTB* that this was a module (with no success). So I changed the "import" to a "require" and this worked.
But now I have about two dozen "imports" in other files giving me the same error.
*I'm sure the root of my problem is that I'm not even sure what's complaining about the issue. I sort of assumed it was Babel 7 (since I'm coming from Babel 6 and I had to change the presets) but I'm not 100% sure.
Most of what I've found for solutions don't seem to apply to straight Node. Like this one here:
ES6 module Import giving "Uncaught SyntaxError: Unexpected identifier"
Says it was resolved by adding "type=module" but this would typically go in the HTML, of which I have none. I've also tried using my project's old presets:
"presets": ["es2015", "stage-2"],
"plugins": []
But that gets me another error: "Error: Plugin/Preset files are not allowed to export objects, only functions."
UPDATE: Here are the dependencies I started with:
"dependencies": {
"@babel/polyfill": "^7.6.0",
"apollo-link-error": "^1.1.12",
"apollo-link-http": "^1.5.16",
"apollo-server": "^2.9.6",
"babel-preset-es2015": "^6.24.1",
回答1:
2020 Update (Node 13.2.0+)
Verify that you have the latest version of Node installed. The --experimental-modules
flag is no longer necessary. Simply do one of the following:
- Add
"type": "module"
to the nearest parentpackage.json
. With this, all.js
and.mjs
files are interpreted as ES modules. You can interpret individual files as CommonJS by using the.cjs
extension.
OR
- Explicitly name files with the
.mjs
extension. All other files, such as.js
will be interpreted as CommonJS, which is the default iftype
is not defined inpackage.json
.
回答2:
According to the official doc (https://nodejs.org/api/esm.html#esm_code_import_code_statements):
import statements are permitted only in ES modules. For similar functionality in CommonJS, see import().
To make Node treat your file as a ES module you need to (https://nodejs.org/api/esm.html#esm_enabling):
- add "type": "module" to package.json
- add "--experimental-modules" flag to the node call
回答3:
I had the same issue and the following has fixed it (using node 12.13.1):
- Change .js files extension to .mjs
- Add --experimental-modules flag upon running your app.
- Optional: add "type": "module" in your package.json
more info: https://nodejs.org/api/esm.html
回答4:
I ran into the same issue and it's even worse: I needed both "import" and "require"
1) Some newer ES6 modules works only with import.
2) Some CommonJS works with require.
Here is what worked for me:
1) Turn your js file into .mjs as suggested in other answers
2) "require" is not defined with ES6 module, so you can define it this way:
import { createRequire } from 'module'
const require = createRequire(import.meta.url);
now 'require' can be used in the usual way.
3) Use import for ES6 modules and require for commonJS.
Some useful links: node.js's own documentation. difference between import and require. Microsoft has some nice documentation about import
Hope this helps
David
回答5:
- I had the same problem when I started to used babel... But later, I had a solution... I haven't had the problem anymore so far... Currently, Node v12.14.1, "@babel/node": "^7.8.4", I use babel-node and nodemon to execute (node is fine as well..)
- package.json: "start": "nodemon --exec babel-node server.js "debug": "babel-node debug server.js" !!note: server.js is my entry file, you can use yours.
- launch.json When you debug, you also need to config your launch.json file "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/babel-node" !!note: plus runtimeExecutable into the configuration.
- Of course, with babel-node, you also normally need and edit another file, such as babel.config.js/.babelrc file
回答6:
My solution was to include babel-node path while running nodemon as follows:
nodemon node_modules/.bin/babel-node index.js
you can add in your package.json script as :
debug: nodemon node_modules/.bin/babel-node index.js
NOTE: My entry file is index.js replace it with your entry file (many have app.js/server.js).
回答7:
I had this problem in a fledgling Express API project.
The offending server code in src/server/server.js
:
import express from 'express';
import {initialDonationItems, initialExpenditureItems} from "./DemoData";
const server = express();
server.get('/api/expenditures', (req, res) => {
res.type('json');
res.send(initialExpenditureItems);
});
server.get('/api/donations', (req, res) => {
res.type('json');
res.send(initialDonationItems);
});
server.listen(4242, () => console.log('Server is running...'));
Here were my dependencies:
{
"name": "contributor-api",
"version": "0.0.1",
"description": "A Node backend to provide storage services",
"scripts": {
"dev-server": "nodemon --exec babel-node src/server/server.js --ignore dist/",
"test": "jest tests"
},
"license": "ISC",
"dependencies": {
"@babel/core": "^7.9.6",
"@babel/node": "^7.8.7",
"babel-loader": "^8.1.0",
"express": "^4.17.1",
"mysql2": "^2.1.0",
"sequelize": "^5.21.7",
"sequelize-cli": "^5.5.1"
},
"devDependencies": {
"jest": "^25.5.4",
"nodemon": "^2.0.3"
}
}
And here was the runner that threw the error:
nodemon --exec babel-node src/server/server.js --ignore dist
This was frustrating, as I had a similar Express project that worked fine.
The solution was firstly to add this dependency:
npm install @babel/preset-env
And then to wire it in using a babel.config.js
in the project root:
module.exports = {
presets: ['@babel/preset-env'],
};
I don't fully grok why this works, but I copied it from an authoritative source, so I am happy to stick with it.
来源:https://stackoverflow.com/questions/58384179/syntaxerror-cannot-use-import-statement-outside-a-module