0

我正在尝试使以下设置正常工作:

  • 标准 Aurelia “Hello World” Typescript 应用程序(由 CLI 创建,由 Webpack 构建)
  • 由使用 webpack-dev-middleware 的 ExpressJS 应用程序提供服务
  • 为了能够在 Aurelia 前端应用程序和 ExpressJS 后端应用程序之间共享代码,一切都结合在一个项目中

我盯着“Hello World”Aurelia 应用程序,将代码移动到一个src/frontend文件夹中,将webpack.config.jstowebpack-frontend.config.js和 npm 脚本重命名为start-frontend等等。经过这些修改,Aurelia 应用程序仍然运行良好。

然后我添加了一个基本的 Express JS 后端应用程序,它有自己的 webpack.config.js、tsconfig.js,当然还有 npm start 脚本,它也可以正常工作。

webpack-dev-middleware最后我试图让 Express 应用程序通过这样的方式启动前端应用程序:

    private applyWebpackDevMiddleware(server: Express) {
        if (Environment.isLocal()) {
            const config = require('../../webpack-frontend.config.js');
            const compiler = require('webpack')(config);

            const webpackDevMiddleware = require('webpack-dev-middleware');
            server.use(
                webpackDevMiddleware(compiler, {
                    hot: true,
                    publicPath: config.output.publicPath,
                    compress: true,
                    host: 'localhost',
                    port: Environment.getPort()
                })
            );

            const webpackHotMiddleware = require('webpack-hot-middleware');
            server.use(webpackHotMiddleware(compiler));
        }
    }

这与直接与 webpack 命令一起使用时可以正常工作的 webpack 配置文件完全相同。但是,像这样,我收到以下错误消息:

(node:15111) UnhandledPromiseRejectionWarning: WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration should be an object.
    at webpack (/Users/will/Desktop/test/aurelia-express/node_modules/webpack/lib/webpack.js:31:9)
    at ExpressServer.applyWebpackDevMiddleware (/Users/will/Desktop/test/aurelia-express/src/backend/ExpressServer.ts:141:48)
    at ExpressServer.setup (/Users/will/Desktop/test/aurelia-express/src/backend/ExpressServer.ts:41:14)
    at Function.createApplication (/Users/will/Desktop/test/aurelia-express/src/backend/Application.ts:18:29)
    at Object.<anonymous> (/Users/will/Desktop/test/aurelia-express/src/backend/index.ts:12:13)
    at Module._compile (internal/modules/cjs/loader.js:816:30)
    at Module.m._compile (/Users/will/Desktop/test/aurelia-express/node_modules/ts-node/src/index.ts:439:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:827:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/Users/will/Desktop/test/aurelia-express/node_modules/ts-node/src/index.ts:442:12)
    at Module.load (internal/modules/cjs/loader.js:685:32)
    at Function.Module._load (internal/modules/cjs/loader.js:620:12)
    at Function.Module.runMain (internal/modules/cjs/loader.js:877:12)
    at Object.<anonymous> (/Users/will/Desktop/test/aurelia-express/node_modules/ts-node/src/bin.ts:157:12)
    at Module._compile (internal/modules/cjs/loader.js:816:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:827:10)
    at Module.load (internal/modules/cjs/loader.js:685:32)
(node:15111) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)

谁能给我一些指示,为什么直接在 webpack 中使用相同的配置文件可以正常工作,但在通过 webpack-dev-middleware 使用时会失败?毕竟,它在同一个项目中具有相同的 node_modules,因此具有相同的 webpack 版本,对吧?

或者是否有人可以共享如上所述的工作设置?谢谢!!

4

2 回答 2

0

由使用 webpack-dev-middleware 的 ExpressJS 应用程序提供服务

ExpressJS 和 webpack-dev-middleware 的组合称为webpack-dev-server. 它在开发中被广泛使用:340 万个存储库依赖于它。它的安装速度是每周700万。仅当您对它的功能不满意或认为您可以提供更好的实现时,在开发中用您开发/组装的东西替换它才有意义。否则,只需在开发中使用它,不要在生产中使用它,因为顾名思义,它webpack-dev-server仅用于开发。

为了能够在 Aurelia 前端应用程序和 ExpressJS 后端应用程序之间共享代码,一切都结合在一个项目中

前端和后端之间的共享非常有意义,将两个项目合并为一个则没有。前端和后端具有不同的运行时和开发依赖关系,您希望在生产中部署后端,这意味着要占用更少的空间,更安全等。因此最好将两个项目分开并通过以下方式实现共享:

  • 在生产中将前端构建工件(html 文件、脚本包)从前端复制到后端,以让 Express 从磁盘提供工件。
  • 在开发中代理以利用webpack-dev-serverLive Reloading 等。
  • 当使用 TypeScript(你这样做)时,可以通过路径映射在项目之间共享代码。

作为一个实际的例子,看看这个项目虽然它不使用 Aurelia。我是作者。

于 2020-03-29T00:43:15.520 回答
0

虽然 winwiz1 确实提供了一些非常有价值的点(例如 TypeScript 路径映射),但我仍然想介绍问题的解决方案,这实际上非常简单:

au new创建一个带有webpack.config.js导出函数的“Hello World”项目。但是,当您想将 webpack 与 Express webapck-dev-middleware 一起使用时,需要一个对象。该对象由文件中的函数返回webpack.config.js。因此,您需要做的就是要求该文件,然后调用该函数:

function applyWebpackDevMiddleware(server: Express) {
    server.use(express.static('static'));

    // Import the function from the webpack config and call the function
    // "false" is the "production" flag
    const config = require('../../webpack.config.js')(false);
    // then us the config object in webpack
    const compiler = require('webpack')(config)

    const webpackDevMiddleware = require('webpack-dev-middleware')
    server.use(webpackDevMiddleware(compiler, {
        writeToDisk: true,
        hot: true,
        publicPath: config.output.publicPath,
        compress: true,
        host: 'localhost',
        port: Environment.getInstance().port
    }))

    const webpackHotMiddleware = require('webpack-hot-middleware')
    server.use(webpackHotMiddleware(compiler))
}
于 2020-03-29T11:15:16.683 回答