Запуск приложения Aurelia CLI Typescript (Webpack) в ExpressJS webpack-dev-middleware

Я пытаюсь заставить работать следующую настройку:

  • Стандартное приложение Aurelia "Hello World" Typescript (созданный CLI, созданный Webpack)
  • Обслуживается приложением ExpressJS с использованием webpack-dev-middleware.
  • Все объединено в один проект, чтобы обеспечить возможность совместного использования кода между интерфейсным приложением Aurelia и внутренним приложением ExpressJS.

Я посмотрел на приложение «Hello World» Aurelia, переместил код в папку src/frontend, переименовал webpack.config.js в webpack-frontend.config.js, а скрипты npm также в start-frontend и так далее. После этих изменений приложение Aurelia по-прежнему отлично работает.

Затем я добавил базовое серверное приложение Express JS со своими собственными webpack.config.js, tsconfig.js и, конечно же, стартовым скриптом npm, который также отлично работает.

Наконец, я попытался заставить приложение Express запускать внешнее приложение через webpack-dev-middleware следующим образом:

    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-dev? В конце концов, это в том же проекте с теми же node_modules и, следовательно, с той же версией веб-пакета, верно?

Или у кого-нибудь есть работающая установка, как описано выше, которой они могли бы поделиться? Спасибо!!


person Will    schedule 28.03.2020    source источник


Ответы (2)


Обслуживается приложением ExpressJS с использованием webpack-dev-middleware.

Комбинация ExpressJS и промежуточного программного обеспечения webpack-dev называется webpack-dev-server. Он очень широко используется в разработке: от него зависят 3,4 миллиона репозиториев. скорость установки составляет 7 миллионов в неделю. Замена его в разработке чем-то, что вы разработали/собрали, имеет смысл только в том случае, если вы либо не удовлетворены его функциональностью, либо считаете, что можете обеспечить лучшую реализацию. В противном случае просто используйте его в разработке и не используйте в производстве, потому что, как следует из его названия, webpack-dev-server предназначен только для разработки.

Все объединено в одном проекте, чтобы иметь возможность обмениваться кодом между интерфейсным приложением Aurelia и внутренним приложением ExpressJS.

Совместное использование между интерфейсом и сервером имеет смысл, а объединение двух проектов в один — нет. Фронтенд и бэкэнд имеют разные зависимости во время выполнения и разработки, вы хотите развернуть бэкенд в производстве, который будет компактным и означает, что он будет занимать меньше места, быть более безопасным и т. д. Поэтому лучше разделить два проекта и добиться совместного использования:

  • копирование артефактов сборки внешнего интерфейса (файлы HTML, пакеты скриптов) из внешнего интерфейса в внутренний в процессе производства, чтобы позволить Express обслуживать артефакты с диска.
  • проксирование в разработке, чтобы воспользоваться преимуществами webpack-dev-server Live Reloading и т. д.
  • при использовании TypeScript (что вы и делаете) совместное использование кода между проектами может осуществляться через сопоставление путей.

В качестве практического примера взгляните на этот проект, хотя он не использует Aurelia. Я автор.

person winwiz1    schedule 29.03.2020
comment
Другим способом совместного использования кода между двумя отдельными проектами может быть подмодуль GIT (или, конечно, третий проект, содержащий общий код, который затем может быть включен как модуль NPM). Я думаю, что с помощью определенных файлов веб-пакетов для внешнего и внутреннего интерфейса можно будет настроить производственные пакеты в соответствии с вашими потребностями. - person Will; 29.03.2020

Хотя winwiz1 действительно предоставил некоторые очень ценные моменты (например, сопоставление путей TypeScript), я все же хотел бы представить решение проблемы, которое на самом деле довольно простое:

au new создает проект "Hello World" с webpack.config.js, который экспортирует функцию. Однако, если вы хотите использовать 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))
}
person Will    schedule 29.03.2020