gpt4 book ai didi

javascript - Webpack 解析别名并在该别名下编译文件

转载 作者:行者123 更新时间:2023-12-02 21:05:36 25 4
gpt4 key购买 nike

我有一个使用 lerna 的项目( monorepo,多个包)。很少有软件包是独立的应用程序。

我想要实现的是在几个包上使用别名来实现依赖注入(inject)之类的功能。例如,我有别名 @package1/backendProvider/useCheckout ,在我的独立应用程序的 webpack 中,我将其解析为 ../../API/REST/useCheckout 。因此,当我将后端提供程序更改为其他内容时,我只会在 webpack 中更改它。

问题

当其他软件包(不是独立应用程序)使用此别名时,就会出现问题。例如:

目录结构如下:

Project
packageA
ComponentA
packageB
API
REST
useCheckout
standalone app

组件A在包A中

useCheckout 位于 /API/REST/useCheckout 路径下的 packageB

ComponentA 使用 useCheckout 以及类似 import useCheckout from '@packageA/backendProvider/useCheckout

的别名

独立应用程序使用组件A

我得到的错误是找不到模块:无法解析'@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;
}

最佳答案

您不需要使用别名。我有一个类似的设置,只需切换到yarn(v1)工作区,它有一个非常聪明的技巧,它将符号链接(symbolic link)添加到根node_modules中的所有包。

这样,每个包都可以毫无问题地导入其他包。

为了使用 lerna 应用 yarn 工作区:

// lerna.json
{
"npmClient": "yarn",
"useWorkspaces": true,
"packages": [
"packages/**"
],
}
// package.json
{
...
"private": true,
"workspaces": [
"packages/*",
]
...
}

这将启用带有lerna的yarn工作空间。

唯一需要解决的问题是让消费者包转译所需的包(因为 babel 和 webpack 的默认配置是忽略 node_module 转译)。

在 Next.js 项目中这很简单,使用 next-transpile-modules .

// next.config.js

const withTM = require('next-transpile-modules')(['somemodule', 'and-another']); // pass the modules you would like to see transpiled

module.exports = withTM();

在使用 webpack 的其他包中,您需要指示 webpack 转译您使用的包(假设它们位于 @somescope/ 的 npm 范围内)。

例如,为了转译 typescript ,您可以添加额外的模块加载器。

// webpack.config.js
{
...
module: {
rules: [
{
test: /\.ts$/,
loader: 'ts-loader',
include: /[\\/]node_modules[\\/]@somescope[\\/]/, // <-- instruct to transpile ts files from this path
options: {
allowTsInNodeModules: true, // <- this a specific option of ts-loader
transpileOnly: isDevelopment,
compilerOptions: {
module: 'commonjs',
noEmit: false,
},
},
}
]
}
...
resolve: {
symlinks: false, // <-- important
}
}

如果您有 css,则还需要添加 css 部分。

希望这有帮助。

额外的优势,yarn 工作区将减少您的 node_modules 大小,因为它会安装一次重复的包(具有相同的 semver 版本)!

关于javascript - Webpack 解析别名并在该别名下编译文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61233457/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com