Как использовать локальные модули в приложении remix-run в рабочих пространствах пряжи
у меня есть
yarn
workspace
monorepo
где разные пакеты содержат повторно используемый код. как
@pkg/styles
,
@pkg/ui-components
все эти пакеты
es modules
(import export statements)
и используются в моем приложении без ssr, созданном веб-пакетом, как это.
Например
import { box } from '@pkg/styles'
import {Button} from '@pkg/ui-components'
теперь мне нужно добавить в тот же монорепозиторий, и все работает нормально, пока я не начну импортировать эти локальные пакеты. я получаю эту ошибку
import box from './box';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1031:15)
at Module._compile (node:internal/modules/cjs/loader:1065:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
если я не ошибаюсь это происходит потому что
esbuild
ожидает всех
node_modules
быть предварительно скомпилирован. и просто игнорирует их в фазе транспиляции.
и мне нужно сказать моему транспилятору, чтобы он учитывал мои локальные пакеты в транспиляции, что очень легко сделать, когда мы используем
webpack
. но я не уверен, как это сделать в
remix-run
и esbuild, который он использует внутри. на github с ремиксами есть несколько проблем, но ничего не помогает.
1 ответ
по состоянию на 3 февраля 2022 г. нет официальной поддержки от remix-run для создания ваших локальных пакетов внутри монорепозитория yarn workspaces. я смог исправить конфигурацию esbuild и разрешить сборку локальных модулей. вот официальная проблема, поднятая в репозитории remix run.
в итоге я исправил конфигурацию remix esbuild
Создавать
esbuild-overrides.js
в корне проекта
добавить следующий код
const esbuild = require('esbuild');
const Module = require('module');
function manualExternalsPlugin() {
return {
name: 'manual-externals-overide',
setup(build) {
build.onResolve(
{
filter: /@YourNamespaceOrPackageName/,
},
(args) => {
return {
external: false,
namespace: args.path,
};
},
);
},
};
}
const originalRequire = Module.prototype.require;
const originalBuild = esbuild.build;
function build(options) {
if (options.platform === 'node') {
const { plugins } = options;
const externalPlugin = plugins.find(
(plugin) => plugin.name === 'manual-externals',
);
const localPlugins = plugins.filter(
(plugin) => plugin.name !== 'manual-externals',
);
localPlugins.push(manualExternalsPlugin());
localPlugins.push(externalPlugin);
return originalBuild({
...options,
plugins: localPlugins,
});
}
return originalBuild({
...options,
});
}
Module.prototype.require = function (id) {
// when remix requires esbuild, it will get our modified build function from above
if (id === 'esbuild') {
return { ...esbuild, build };
}
return originalRequire.apply(this, arguments);
};
обновить скрипты сборки
"scrips": {
"dev:patched": "NODE_OPTIONS='-r ./esbuild-overrides' remix dev",
"build:patched": "NODE_OPTIONS='-r ./esbuild-overrides' remix build"
}