mmm*_*mmm 4 javascript webpack babeljs lerna next.js
我有一个使用 lerna 的项目( monorepo,多个包)。很少有软件包是独立的应用程序。
我想要实现的是在几个包上使用别名来实现依赖注入之类的功能。例如,我有别名@package1/backendProvider/useCheckout,在我的独立应用程序的 webpack 中,我将其解析为../../API/REST/useCheckout. 因此,当我将后端提供程序更改为其他内容时,我只会在 webpack 中更改它。
当其他软件包(不是独立应用程序)使用此别名时,就会出现问题。例如:
目录结构如下所示:
Project
packageA
ComponentA
packageB
API
REST
useCheckout
standalone app
Run Code Online (Sandbox Code Playgroud)
组件A位于packageA中
useCheckout 位于 packageB/API/REST/useCheckout路径下
ComponentAuseCheckout与别名一起使用,例如import useCheckout from '@packageA/backendProvider/useCheckout
独立应用程序使用组件A
我得到的错误是Module not found: Can't resolve '@packageA/backendProvider/useCheckout
但是,当在独立应用程序(具有下面提供的配置的 webpack)中使用相同的别名时,它可以正常工作。仅当依赖项出现问题时。
我知道一种解决方案是使用 webpack 编译每个包 - 但这看起来并不友好。我认为可行的是告诉 webpack 将这些别名解析为目录路径,然后重新编译它。第一部分(解析别名)已完成。
当我使用 NextJS 时,我的 webpack 配置如下所示:
webpack: (config, { buildId, dev, isServer, defaultLoaders }) => {
// Fixes npm packages that depend on `fs` module
config.node = {
fs: "empty"
};
const aliases = {
...
"@package1/backendProvider": "../../API/REST/"
};
Object.keys(aliases).forEach(alias => {
config.module.rules.push({
test: /\.(js|jsx)$/,
include: [path.resolve(__dirname, aliases[alias])],
use: [defaultLoaders.babel]
});
config.resolve.alias[alias] = path.resolve(__dirname, aliases[alias]);
});
return config;
}
Run Code Online (Sandbox Code Playgroud)
您不需要使用别名。我有一个类似的设置,只需切换到yarn(v1)工作区,它做了一个非常聪明的技巧,它将符号链接添加到根node_modules中的所有包。
\n这样,每个包都可以毫无问题地导入其他包。
\n为了将纱线工作区与 lerna 一起应用:
\n// lerna.json\n{\n "npmClient": "yarn",\n "useWorkspaces": true,\n "packages": [\n "packages/**"\n ],\n}\nRun Code Online (Sandbox Code Playgroud)\n// package.json\n{\n ...\n "private": true,\n "workspaces": [\n "packages/*",\n ]\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n这将使 lerna 启用纱线工作区。
\n唯一需要解决的问题是让消费者包转译所需的包(因为 babel 和 webpack 的默认配置是忽略 node_module 转译)。
\n在 Next.js 项目中,这很简单,使用next-transpile-modules。
\n// next.config.js\n\nconst withTM = require(\'next-transpile-modules\')([\'somemodule\', \'and-another\']); // pass the modules you would like to see transpiled\n \nmodule.exports = withTM();\nRun Code Online (Sandbox Code Playgroud)\n在使用 webpack 的其他包中,您需要指示 webpack 转译您使用的包(假设它们位于 npm 范围内@somescope/)。
例如,为了转译打字稿,您可以添加额外的模块加载器。
\n// webpack.config.js\n{\n ...\n module: {\n rules: [\n {\n test: /\\.ts$/,\n loader: \'ts-loader\',\n include: /[\\\\/]node_modules[\\\\/]@somescope[\\\\/]/, // <-- instruct to transpile ts files from this path\n options: {\n allowTsInNodeModules: true, // <- this a specific option of ts-loader\n transpileOnly: isDevelopment,\n compilerOptions: {\n module: \'commonjs\',\n noEmit: false,\n },\n },\n }\n ]\n }\n ...\n resolve: {\n symlinks: false, // <-- important\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n如果您有 css,则还需要添加 css 部分。
\n希望这可以帮助。
\n额外的优势是,yarn 工作空间将减少您的node_modules大小,因为它会安装一次重复的包(具有相同的 semver 版本)!
| 归档时间: |
|
| 查看次数: |
6514 次 |
| 最近记录: |