Webpack 抛出'Illegal import declaration',疑似配置错误

Webpack throws 'Illegal import declaration', suspected config error

我正在尝试编译我的 Javascript (es6) 以供服务器端使用,我的目标环境包括:

node    8.9.1  
npm     6.0.0  
webpack 4.8.1

我尝试使用 webpack 编译的代码的第一部分是文件 index.js,它是这样开始的。

import express from 'express';
import https from 'https';

// Import socket.io
let io = require('socket.io').Server;

// Now import some basic middleware for express
import * as session from 'express-session';
import * as bodyParser from 'body-parser';
import * as favicon from 'serve-favicon';

// Import useful file IO
import * as path from 'path';
let fs = require('fs');
...

但是当我 运行 webpack 我得到以下错误:

$ webpack

Webpack is watching the files…

Hash: 1bd3f903f9c5ccdc3456
Version: webpack 4.8.1
Time: 684ms
Built at: 2018-05-10 14:51:08
                       Asset      Size  Chunks             Chunk Names
                   server.js  3.97 KiB    main  [emitted]  main
               server.js.map  2.52 KiB    main  [emitted]  main
../dist/keys/it-test-crt.crt  1.16 KiB          [emitted]  
  ../dist/images/favicon.ico  1.19 KiB          [emitted]  
../dist/keys/it-test-csr.pem  1.02 KiB          [emitted]  
../dist/keys/it-test-key.pem  1.64 KiB          [emitted]  
Entrypoint main = server.js server.js.map
[./index.js] 1.2 KiB {main} [built] [failed] [1 error]

ERROR in ./index.js
    Module build failed: Error: Parse Error: Line 1: Illegal import declaration
...

顺便说一句,我在它的 es6 化身中使用 Javascript,所以确实需要 Bable,它在我的配置中 (q.v)。即使我没有使用 es6,Webpack 文档也建议无论如何都应该尊重 import,请参阅 here,其中 Webpack 文档说:

webpack 的第 2 版原生支持 ES6 模块语法,这意味着您可以使用导入和导出,而无需像 babel 这样的工具来为您处理。

所以我的问题是为什么我会看到上面的错误?我目前的假设是我在 Webpack 配置的某个地方犯了一个错误,见下文:

var nodeExternals = require('webpack-node-externals');
var CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
    context:        __dirname,

    mode:           'development',

    entry:          './index.js',

    output:         {
                    filename:   'server.js',
                    path:        __dirname + '/../dist/'
                    },

    devtool:        'source-map',

    resolve:        {
                    extensions: ['.js', '.jsx', '.json'],
                    modules: ['./', 'node_modules']
                    },

    module:         {
                    rules:[
                            {
                            test: /\.js?$/,
                            use: {
                                loader: 'babel-loader?presets[]=env',
                                }
                            },
                            {
                            test: /\.jsx?$/,
                            use: {
                                loader: 'jsx-loader?harmony'
                            }
                            },
                            {
                            enforce: 'pre',
                            test: /\.js$/,
                            loader: 'source-map-loader'
                            }
                        ]
                    },

    target:         'node',

    node:           {
                    __dirname: false,
                    __filename: false
                    },

    externals:      [nodeExternals()],

    watch:          true,

    watchOptions:   {
                    ignored: /node_modules/
                    },

    plugins:        [
                    new CopyWebpackPlugin([
                        {from:  'images',   to: '../dist/images'},
                        {from:  'keys',     to: '../dist/keys'}
                        ])
                    ]
  };

我没有设置 .babelrc 文件,因为我将 presets[]=env 查询附加到 babel-loader。以防万一了解任何其他版本号会有所帮助,我的 package.json 看起来像这样:

{
"name": "web-app",
"version": "1.0.0",
"description": "A web application using react, etc. ",
"main": "index.js",
"repository": {
    "type": "git",
    "url": "git+https://github.com/nigel-daniels/web-app.git"
    },
"keywords": [
    "web",
    "app",
    "react",
    "redux"
    ],
"author": "Nigel Daniels",
"license": "MIT",
"bugs": {
    "url": "https://github.com/nigel-daniels/web-app/issues"
    },
"homepage": "https://github.com/nigel-daniels/web-app#readme",
"dependencies": {
    "async": "^2.6.0",
    "bcrypt-nodejs": "0.0.3",
    "body-parser": "^1.18.2",
    "cookie-parser": "^1.4.3",
    "debug": "^3.1.0",
    "express": "^4.16.2",
    "express-session": "^1.15.6",
    "express-socket.io-session": "^1.3.2",
    "fs": "0.0.1-security",
    "immutable": "^3.8.2",
    "mongoose": "^5.0.6",
    "nodemailer": "^4.4.0",
    "passport": "^0.4.0",
    "passport-local": "^1.0.0",
    "react": "^16.1.1",
    "react-dom": "^16.1.1",
    "redux": "^3.7.2",
    "serve-favicon": "^2.4.5",
    "socket.io": "^2.0.4"
    },
"devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.6.1",
    "chai": "^3.5.0",
    "chai-immutable": "^1.6.0",
    "copy-webpack-plugin": "^4.2.3",
    "jsx-loader": "^0.13.2",
    "mocha": "^5.0.1",
    "source-map-loader": "^0.2.3",
    "webpack": "^4.8.1",
    "webpack-node-externals": "^1.7.2"
    },
"engines": {
    "node": "^8.1.0",
    "npm": "6.0.0"
    }
}

感谢任何建议!

我认为问题在于 express 模块使用 module.exports 导出,而你 import 使用 es2015 导入。我认为 webpack 本身不支持转换。我只会在导入 npm 模块时使用 require 代替,否则你这个 babel 插件可能会为你解决它:https://www.npmjs.com/package/babel-plugin-transform-es2015-modules-commonjs.

您不需要 jsx-loader 来构建 nodejs 后端。您可以删除它,如有必要,让 babel-loader 为您处理 .jsx 扩展:

{
  test: /\.jsx?$/, // notice the little 'x'
  use: {
      loader: 'babel-loader?presets[]=env',
    }
 },