现在,我们中的一些人发布了用 ES2015 编写的 NPM 包(特别是组件),而无需转译它们。
这是一件非常好的事情,特别是如果它们将用于 Next.js 或 CRA(进行转译)之类的项目。 它们提供以下好处:
但是我们现在不能这样做,我们将node_modules 中的所有内容从 babel 转译中
所以,这是建议的解决方案。
我们在next.config.js
有一个条目来包含需要通过 babel 的模块。 看:
module.exports = {
transpileModules: [
"my-component",
"redux/src"
]
}
webpack()
扩展名不可行?transpileModules
听起来更好为什么这对 webpack() 扩展不可行?
我希望你的意思是自定义 webpack 配置。 这是可行的。 但这位于现有的加载器中。 得到它有点困难。
transpileModules
听起来更好
惊人的。 我来更新。
我们会接受正则表达式吗?
是的。 当然。
嘿,
当我开始自己的网站时,我正在尝试像 Lerna/Next/Styled... 这样的新技术,并且很乐意提供有关此的早期反馈。
我打开了一个重复的问题,我试图在我的 NextJs 模块中导入/转译基于 CRA 的模块,但不知道如何进行转译(请注意,我想让我的模块作为独立运行)
我还注意到,同样基于 Lerna 的 Babel 在暴露每个模块之前会对其进行转译,但在我看来,最好像@arunoda建议的那样
我想为我的客户端提供一个 babel 配置,并与我所有的解耦模块共享该配置。 如果我想保持在 Next runner 之外独立运行我的模块的能力,这可能不是那么容易
我当前的测试项目在这里: https : @arunoda你在努力吗?
@slorber目前我们专注于 2.0 版本,我们正在微调内容并尽可能查找错误。
我还没有开始做这方面的工作,但我们可以在 2.0.0 之后做到这一点。
好的,所以我会做一个叉子。 我已经在运行 2.0.0 测试版,因为我没有构建一个关键网站,而且我认为 webpack 1.13 没有解决jsnext:main/module字段。
我不是打包专家,但我想我宁愿使用 package.json 的“模块”字段,不是吗? 据我所知,“main”似乎是已经转译的代码。 但是由于 webpack 配置允许包含/排除转译,我不确定它是否相关。 关于我更愿意使用的 3 个字段中的哪一个的任何建议?
@slorber我认为 webpack 只支持main
就像 NPM 一样。 你可以用那个。
我们可以检查该文件路径exclude
在我们的函数next.conf.js
嗯,根据我在针对 Next 2.x 的实践中所看到的,我看到模块工作(但在运行时由于未转译而失败)而jsnext:main没有工作(据我所知)。 不过应该是支持的。
无论如何, jsnext:main或 module 似乎不是这个问题的解决方案,所以对于公司内部的模块,只启用转译可能就足够了
社区尚未就一种方法达成一致,对吗? 例如,我可以开箱即用地使用react-youtube
另一个。 我假设有大量模块在发布之前进行转换?
参考: https :
是的,在发布之前始终进行转换是有意义的,因为您不知道模块将被谁/如何使用,并且您不想强制客户端为您的库设置适当的 babel 设置。 这就是Rollup 的建议:发布以不同方式转译的模块,以便捆绑程序可以决定使用哪个。
但是对于公司内部包,转换设置可能在多个项目中是相同的(例如 babel 预设),并且让客户端打包程序转换所有公司依赖项对我来说是有意义的
非常同意@slorber - 如果您正在分解项目并尽可能地隔离事物,这对于内部模块将非常方便。
并且@rauchg / @arunoda支持 RegExp 会非常好,所以你可以有一个条目来捕获所有公司内部模块,使用 NPM org 命名空间:
// next.config.js
module.exports = {
transpileModules: [
/^\@my-npm-org\/.*/
]
}
美丽的建议@philcockfield
嘿,也许值得提供一些预设。 在我看来,大多数工具(Lerna/npm 链接...)都依赖于符号链接,所以为什么不使用以下简单的方法:
```javascript
模块.出口 = {
transpileModules: ["符号链接"]
}
````
我越认真地使用next.js
,并围绕它构建了一个丰富的模块库,这个特性就变得越重要。 它正在成为一个真正的 PITA,在我的内部模块中复制 babel 编译步骤。
🚀🤖
我今天正在做这个:)
@philcockfield试试这个: https :
谢谢@arunoda
因此,正如对您的 PR 的评论,如果这不支持符号链接,该功能将受到一些限制,因为它不适用于 npm 链接或 Lerna,但仅适用于未转译的 npm 模块(对吗?我没有看到任何其他用例,除非您在/node_modules
内提交模块)
为什么不支持符号链接? 是不是更难支持?
此外,我想在我的应用程序上测试您的分支,但我不确定这样做的最佳方法是什么。 是否有任何已知的程序,以便我们可以轻松地测试分支,并且对测试人员来说不会太痛苦? 我试过一些东西,如:
目前测试分叉的最佳方法是什么?
如果您正在考虑使用next.config.js
: module.exports = { webpack: (config
,那么config.module.rules
有一些事情,看起来您需要更改其中一项规则,还是添加一项? :
{ loader: 'babel-loader',
include: '/Users/me/gh/guide/node_modules/next/dist/pages',
options:
{ babelrc: false,
cacheDirectory: true,
sourceMaps: 'both',
plugins: [Object] } },
{ test: /\.js(\?[^?]*)?$/,
loader: 'babel-loader',
include:
[ '/Users/me/gh/guide',
'/Users/me/gh/guide/node_modules/next/dist/pages' ],
exclude: [Function: exclude],
query:
{ babelrc: true,
cacheDirectory: true,
sourceMaps: 'both',
presets: [] } } ]
期待更简单的语法建议。
抱歉我的无知我看不出这个问题的解决方案是什么? 我们很想将 es6 导入我们的代码库,我们需要 tree-shaking 。
这个有PR吗?
@andrewmclagan这个问题仍然是开放的,并且有一个相关的PR可能不会满足所有人(比如 LernaJS 用户)
这是什么状态? 有没有其他方法可以让 next 的 webpack 转译从 node_modules 导入的文件?
@slorber我会看一下 PR。 贡献我们的用例。
我面临着类似的问题。 尝试使用get-urls
包。 可以用dev
找到,但是当我编译它时。 我从 uglify 得到错误
...
{ Error: commons.js from UglifyJs
...
请问有什么解决方法吗?
Arunoda 将在这里的某个时间处理它。 他之前做过#749
我很想看到这个功能被实现。 正如@philcockfield 所提到的,构建依赖于 Next.js 转译的模块库是一个常见的场景,并且能够在项目之间共享组件会很棒。
这不仅需要用于摇树。 也适用于像styled-jsx
这样的 babel 插件。 因此,如果您有一个使用 babel 插件的模块(如库),最好的解决方案是包含 ES6 源代码并允许您的应用程序从 node_modules 转译它。 当然 next 默认已经包含了styled-jsx
。
这是我所做的
// next.config.js
exports.webpack = config => (config.module.rules = config.module.rules.map(({exclude, ...rest}) => ({
exclude: Object.prototype.toString.call(exclude) === '[object Function]' ? (str => !/mycomponents/.test(str) && exclude(str)) : exclude,
...rest
})), config);
我基本上用自定义函数替换了每个exclude
。
我不知道我做错了什么,但我无法让它发挥作用。
我需要node_modules/mycomponents
的内容也被 Next.js 转译
如果我用空数组完全覆盖所有排除,它甚至不起作用
exports.webpack = config => (config.module.rules = config.module.rules.map(({exclude, ...rest}) => ({
exclude: [],
...rest
})), config);
请帮我 :)
谢谢
嘿伙计们 ( @thealjey )jsnext:main
驱动的模块。
jsnext:main
在 package.json 中,则转换指定的入口点,否则导入main
我没有使用next.js
但我希望它有所帮助。
@damianobarbati不,不幸的是它没有
直接配置 webpack 以转译任何内容并不困难,但我正在努力在 Next.js 的上下文中完成这项工作
大家好,有人找到解决办法了吗?
我有一个本地 ES6 链接节点模块,我需要在我的项目中导入,但我无法正确使用 webpack 巫毒!
我确定有更好的方法,但我们在构建时通过 babel 运行所有内容:
next build && babel .next/*.js --out-dir . --presets=es2015,react
这是死了吗? 我正在寻找一种转换自定义模块的方法,但似乎仍然不可能。
@mattfelten它在 v5 的路线图上👍
有没有人有一个解决方法的例子?
@timneutkens有这方面的时间表吗? 意识到这通常是一个不可能的问题,但我们正在努力确定我们目前在工作中的筹码量,这对我们来说是一个非常大的障碍! :)
解决方法建议也有效。
@thealjey意识到这是一条旧评论,但您的解决方案可能不起作用,因为还指定了include
需要覆盖。
更新:研究了这个策略,但考虑到 next.js 内部配置中不同模块目录的所有不同加载器,它并不明智。 这将需要是一流的。
@chrisui我的(临时)解决方案是使用babel-plugin-module-resolver ,配置如下 - "plugins": [["module-resolver", {"root": ["./"]}]]
这绝不是一个完美的解决方案,但是,由于其他一切都失败了,它现在有效
多亏了我不需要每次导入都写一堆../
对于某些人来说,这实际上可能是更好的解决方案,尽管它肯定无助于可重用性
@thealjey你能举个例子吗?
我有一个项目设置,我尝试此操作无济于事...
https://github.com/jamesgorrie/nappy
我很乐意尝试获得 PR,因为这会让我们的生活变得更加轻松,但有一些问题,例如: next.js
是否应该支持某些模块的转译,或者这应该由转译器决定,但是next.js
更严格地遵循模块解析。 作为next.js
新手,不确定该问谁或从哪里开始。
它在 v5 的路线图上👍
@timneutkens 是否已将其纳入 v5?
想知道。
只要看看它合并的地方。 这是8天前合并的。 5.0.0 于 2 天前发布。 从金丝雀分支合并到...
有没有人有关于如何实施的例子? 如上所述,它应该像这样工作吗?
module.exports = {
transpileModules: ['my-npm-module']
}
或者看起来不一样?
我糊涂了。 @timneutkens上述链接指向仍处于打开状态的 PR。 这还没有在 v5 中合并吗?
编辑:没关系,这只是一个突出例子的公关。
这是一个示例,您可以在不合并的情况下使用该示例。 transpileModules
是我们稍后会解决的问题。
作为一般经验法则:当一个问题处于开放状态时,它不会被发布。
@brianyingling我已经把这个例子变成了一个临时解决方案的插件(仅限 v5)。
目前它正在为我们工作,直到更强大的官方解决方案到位。
https://www.npmjs.com/package/@weco/next -plugin-transpile-modules
我很想看到应用程序代码库中单个模块的示例。
例如,我有一个同时使用服务器端和客户端的模块。 我无法通过将模块分解为自己的单独模块并yarn link
对其进行分解,或者通过破解 webpack 规则来使上述任何示例工作。
这是一个简单的重现: https :
// pages/index.js
import { foo } from '../lib/test'
export default () => <div>hello {String(typeof foo)}</div>
// lib/test.js
async function foo () {}
module.exports = { foo }
@timneutkens告诉我这是因为我在共享模块中使用了async/await
。 我想我的解决方案可能是删除 async/await 并将所有内容更改为.then()
样式的回调。
好的,我找到了一个适合我的修复程序。
首先,我根据https://github.com/zeit/next.js/issues/3018#issuecomment -380879576 在我的next.config.js
配置中添加了config.resolve.symlinks = false
设置
// next.config.js
webpack: (config, { dev }) => {
config.resolve.symlinks = false
return config
}
然后我将我的共享库——一个使用 CommonJS 导出和async
/ await
关键字的.js
文件——放在名为shared
的应用程序的子目录中:
// shared/index.js
async function foo () {}
module.exports = { foo }
// shared/package.json
{
"name": "@myapp/shared",
"version": "1.0.0",
"main": "index.js",
"license": "UNLICENSED",
"private": true,
"dependencies": { ... }
}
最后,当有人在主应用程序中执行yarn install
,我添加了一个postinstall
脚本将它们链接在一起:
// package.json
{
...
"scripts": {
"postinstall": "cd shared ; yarn -s unlink ; yarn link && yarn && cd .. && yarn link @myapp/shared",
...
现在我的 Mocha 测试在服务器端通过了,我的自定义 Koa 服务器启动正常,并且我的 NextJS 页面中不再有疯狂的Cannot assign to read only property 'exports' of object '#<Object>'
。
升级到 NextJs 5.1.0 时我遇到了同样的问题。 next 中的一两个节点模块没有转译胖箭头函数并在 IE11 中抛出错误。 我之前已经设置了单独的 polyfill,最后我选择在我的next.config.js
使用babel-polyfill
定位这些模块文件:
module.exports = {
webpack: (config, { dev }) => {
const polyfill = new Promise((resolve, reject) => {
const originalEntry = config.entry
originalEntry().then(entries => {
if (entries['main.js']) {
entries['main.js'].unshift('./client/polyfills.js')
entries['main.js'].unshift('babel-polyfill')
}
config.entry = entries
resolve()
})
})
config.module.rules.push(
{
test: path.resolve('./node_modules/next/node_modules/'),
loader: 'babel-loader',
options: {
babelrc: false,
cacheDirectory: false,
presets: ['es2015']
}
}
)
return polyfill.then(() => { return config })
}
}
希望这可以帮助某人。
ESM就像一种魅力。
使用index.js
的自定义 Next.js 服务器,我可以运行此命令来启动服务器并且 esm 完美启动,解析 Lerna 符号链接项目包中的 ES 模块。
node -r esm index.js
@curran很酷,它可以代替 babel-node 吗?
@curran我会避免在生产中这样做
@blackbing我不知道。
@thealjey为什么会这样?
如果有人正在寻找快速简便的解决方案,这就是我所做的。 我创建了一个子目录shared/
,其中包含我们希望通过独立 Node 脚本在后端和通过 NextJS 在客户端上运行的任何代码。 它有自己的package.json
并将其名称声明为@myproject/shared
。
然后,在主(父)项目中,我向package.json
添加了一个安装后脚本,如下所示: cd shared && yarn -s unlink >/dev/null 2>&1 ; yarn -s link && yarn -s && yarn link @myproject/shared
— 然后至少运行yarn
一次,并将导入更改为import { whatever } from '@myproject/shared/somefile'
这样,共享代码无需任何疯狂的转译步骤即可工作,而且每次进行更新时您都不必重新运行yarn
/ npm
因为yarn link
使符号链接。
对于那些使用 TypeScript 的人, @weco/next-plugin-transpile-modules
不应该工作。 我创建了一个 fork 来处理 Next 的withTypescript
: https :
不过,当我们也需要在 TypeScript 中使用服务器端代码时,我仍然需要弄清楚如何正确地做事。
有这方面的消息吗?
@bogdansoare我正在使用https://github.com/KeitIG/next-plugin-transpile-modules
我的另一个,在以下要点中。 它处理 TypeScript,以及@scope
特定包,而不是所有包。 https://gist.github.com/trusktr/44400d0d016c506629b4f914799dc9cd
个人使用以下next.config.js
:
module.exports = {
webpack: (config, options) => {
config.module.rules.push({
test: /\.js$/,
include: /node_modules/,
use: [
options.defaultLoaders.babel
]
})
return config
}
}
它包含node_modules
,这是我实现 IE 11 兼容性所需要的...
我也很欣赏这个解决方案,努力将非转译的 npm 包添加到我的项目中。 现在不得不将它们下载到供应商/ :(
真烦人
@bel0v我相信你应该已经能够用next-plugin-transpile-modules
来完成这个。 这个问题应该很可能被关闭。 抄送/ @timneutkens
我仍然想研究替代解决方案。
最近 Jamie 写了一篇关于编译 node_modules 问题的非常详细的帖子: https ://twitter.com/jamiebuilds/status/1080840492525350912
我阅读了 Jamie 的帖子,但我也想分享 Henry Zhu 和 Babel 对这种情况和解决方案的看法。
https://babeljs.io/blog/2018/06/26/on-sumption-and-publishing-es2015+-packages
(不反对蒂姆,只是想我会分享,许多优点和缺点。可能有助于蒂姆研究替代解决方案)
是的,过去半年我们一直在和很多人讨论这个问题,包括亨利😄
尽管担心转译 node_modules,但希望在 monorepo 中转译您自己的包是一个非常普遍的要求,这些问题并不适用
@dcalhoun我试过了,但不幸的是我仍然遇到意外的令牌错误。 此插件有一个未解决的 Next 7 问题,可能与此相关
@martpie是的,我相信我已经尝试过了..无论如何我会再试一次
@martpie我们已经开始使用 next7 和一致的 babel.config.js 和 yarn 工作区,我可能会看看我是否可以设置一个简单的例子。
我在这里分叉了基本示例
https://github.com/bel0v/learnnextjs-demo
在其中,我安装了一个未转译的依赖项(有线元素),得到了一个构建错误Unhandled Rejection (SyntaxError): Unexpected token {
并尝试以建议的方式修复它。
我在想也许我需要一些额外的 babel 插件才能让它工作..🤔
@bel0v再次出现在常见问题解答中,解释了为什么 Lerna 设置不起作用(TL,DR;您可能使用的是错误的)
@martpie啊,明白了! 没有意识到第三方包是用 Lerna 设置的。 谢谢
似乎https://twitter.com/jamiebuilds已暂停,因此无法再阅读那里的线程。 #3018 关于此问题已关闭,所以我想知道正在考虑的替代方法是什么?
对于这些用例 atm,这些是否代表了 next.js 的最新技术/最佳实践?
https://github.com/curran/nextjs-esm-example
https://github.com/wellcometrust/next-plugin-transpile-modules
https://github.com/martpie/next-transpile-modules
https://github.com/zeit/next.js/tree/canary/examples/with-yarn-workspaces
所以,如果你和我一样,正在开发一个必须支持 IE11 的项目,你真的必须转译node_modules/
所有代码。 在 Next.js 7.x 中,我使用了以下设置,效果很好。
不幸的是,它在 Next.js 8.x 中停止工作,错误是模块无法导入其他模块,因为它们没有默认导出。 然后我想出了 Next.js 8.x 的以下配置,它只用@babel/preset-env
转译node_modules/
的代码,没有其他插件。
这是通过在package.json
设置我的browserlist
属性来组合的:
"browserslist": "defaults, IE >= 11, EDGE >= 14, Safari >= 11, Chrome >= 41, Firefox >= 52",
next.config.js
module.exports = {
webpack: (config, options) => {
config.module.rules.push({
test: /\.js$/,
include: /node_modules/,
use: [
options.defaultLoaders.babel,
],
})
return config
},
}
next.config.js
module.exports = {
webpack: (config, options) => {
config.module.rules.push({
test: /\.js$/,
include: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-syntax-dynamic-import'],
},
},
})
return config
},
}
不幸的是,我还没有想出如何在这个设置中使用@babel/plugin-transform-runtime
,所以它可能会在代码中吐出不少助手😞 希望 gzip 能解决它😆 😅
我认为如果 Next.js 可以给我们一个选项来正确地转换node_modules/
以与您拥有的任何browserlist
一起工作,那将会很棒。 似乎任何拥有企业用户的大型网站都依赖于此来正确支持旧浏览器。
作为next-transpile-modules
的维护者(基于@jamesgorrie 的出色工作),我很高兴在这里帮助任何遇到此问题的人。
我已经使用这个插件从事专业项目一年多了,到目前为止它运行得很好。
Next.js 的原生支持当然很棒,我很乐意帮助将此功能集成到next
包中。 我知道蒂姆有一些他想尝试的想法,但无论如何。
干杯!
@martpie我很快查看了您的项目,但没有找到一种快速转换 _all_ 模块的方法,这可能吗? ☺️
另外,我看到您正在选择options.defaultLoaders.babel
并将其用作 babel 加载器。 在使用 Next.js 8.x 执行此操作时,我遇到了一些模块在此之后无法正确识别为 CJS 模块的问题,然后其他库将无法导入它们,例如:
./pages/_glamor.js
Attempted import error: 'css' is not exported from 'glamor'.
./components/project-selector.js
Attempted import error: 'react-select/lib/Async' does not contain a default export (imported as 'AsyncSelect').
./node_modules/react-select/dist/react-select.esm.js
Attempted import error: 'react-input-autosize' does not contain a default export (imported as 'AutosizeInput').
./pages/signup/full.js
Attempted import error: 'react-select/lib/Creatable' does not contain a default export (imported as 'CreatableSelect').
./components/markdown-editor.js
Attempted import error: 'react-simplemde-editor' does not contain a default export (imported as 'SimpleMDEEditor').
./components/pagination.js
Attempted import error: 'react-js-pagination' does not contain a default export (imported as 'UpstreamPagination').
./node_modules/react-google-recaptcha/lib/es/recaptcha-wrapper.js
Attempted import error: 'react-async-script' does not contain a default export (imported as 'makeAsyncScriptLoader').
./pages/_glamor.js
Attempted import error: 'rehydrate' is not exported from 'glamor'.
这就是为什么我转而为node_modules/
提供自定义 babel 配置,它只使用preset-env
转换代码,并跳过 Next.js 特定的转换。 您如何看待这种方法?
干杯🍻
@LinusU也许试试transpileModules: ['(.*?)']
并告诉我它是否有效?
但它可能在未来的主要版本中不起作用,所以要小心。
更一般地说,我不建议(阅读“非常不鼓励”)转译整个node_modules
文件夹,编译将花费很长时间,并且包应该提供与 ES3 兼容的代码(因此与 IE11 兼容)。
只转译你需要的模块! (如lodash-es
,本地模块等...)
包应该提供兼容 ES3 的代码(因此兼容 IE11)。
这不是我所看到的现实,我实际上并不同意。 模块作者永远不会确切知道我的目标浏览器,如果他们发布旧代码,他们可能会惩罚以现代浏览器为目标的用户。
编译需要很长时间
对我来说启动时有点慢,但在那之后,它似乎被缓存了,当对特定页面进行更改时,我看到近乎即时的重新加载。
只转译你需要的模块!
这将要求我确切地知道哪些包与 IE11 兼容,哪些不兼容,以及在任何依赖项(甚至是瞬态依赖项)发生变化时随时更新此信息。 我不明白这是多么现实🤔
重要的是 package.json module
中提供的 ESM 入口点通常是ES5和 ES6 导入/导出,用于摇树。 因此,除非另有说明,否则这是打包器 (Webpack) 而不是转译器 (Babel) 的工作。 许多维护良好的软件包已经具有 ESM 入口点,例如 OP 提到的 Redux 的redux/es
。
如果您正在考虑使用
next.config.js
:module.exports = { webpack: (config
,那么config.module.rules
有一些事情,看起来您需要更改其中一项规则,还是添加一项? :{ loader: 'babel-loader', include: '/Users/me/gh/guide/node_modules/next/dist/pages', options: { babelrc: false, cacheDirectory: true, sourceMaps: 'both', plugins: [Object] } }, { test: /\.js(\?[^?]*)?$/, loader: 'babel-loader', include: [ '/Users/me/gh/guide', '/Users/me/gh/guide/node_modules/next/dist/pages' ], exclude: [Function: exclude], query: { babelrc: true, cacheDirectory: true, sourceMaps: 'both', presets: [] } } ]
期待更简单的语法建议。
对我来说很好用
{
test: /\.js(\?[^?]*)?$/,
loader: 'babel-loader',
include: [
path.resolve(__dirname, './node_modules/next/dist/pages'),
],
query: {
cacheDirectory: true,
sourceMaps: 'both',
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-proposal-object-rest-spread']
}
},
我在使用 Lerna mono repo 时遇到了这个问题,并且正在摸索原因是什么。 由于错误来自 webpack,除了缺少加载程序之外,它没有提供很好的细节,这没有帮助。 谢天谢地,我发现了这个 github 问题!
我将把我的解决方案留在这里,供其他搜索此问题的人使用,并且也在使用 Lerna:
为共享包创建一个预发布脚本,将源代码转换为 dist 目录,并在链接时告诉 Lerna 指向 dist 目录:
// package.json
"main": "dist",
"scripts": {
// I'm using the react-app preset because it's easy
"prepublish": "babel --presets react-app --plugins @babel/plugin-transform-modules-commonjs src --out-dir dist"
},
// This instructs Lerna to use dist when symlinking
"publishConfig": {
"directory": "dist"
}
现在,当您lerna bootstrap
它会运行预发布脚本并转译源代码,以便 Next 可以使用它。
如果您使用lerna
您可以制作符号链接以使用next-transpile-modules 进行转换。 如何使用带有lerna
的包写在文档的底部。
对于在 NextJs 应用程序之间搜索共享代码的任何人,我只想报告@LinusU的解决方案在尝试在我的 Mono 存储库中的多个 NextJs 应用程序之间共享 React 组件和实用程序时对我有用:
// next.config.js
const aliasPathsToResolve = [
{ name: 'components', path: path.resolve(__dirname, './components') },
{ name: 'Common', path: path.resolve(__dirname, '../../common/react/') },
]
module.exports = () => {
return {
webpack(config, { defaultLoaders }) {
config.module.rules.push({
test: /\.(js|jsx)$/,
include: [path.resolve(__dirname, '../../common/react/')],
use: [defaultLoaders.babel],
})
/** Resolve aliases */
aliasPathsToResolve.forEach((module) => {
config.resolve.alias[module.name] = module.path
})
}
}
}
在撰写本文时,我正在使用最新版本的 NextJs。
@Lwdthe1我试过你的代码,最初得到这个错误:
TypeError: Cannot read property 'then' of undefined
at getBaseWebpackConfig (/c2/wiz-frontend/packages/pipeline-view/node_modules/next/dist/build/webpack-config.js:85:25)
at async Promise.all (index 0)
at async HotReloader.start (/c2/wiz-frontend/packages/pipeline-view/node_modules/next/dist/server/hot-reloader.js:14:1675)
at async DevServer.prepare (/c2/wiz-frontend/packages/pipeline-view/node_modules/next/dist/server/next-dev-server.js:7:223)
at async /c2/wiz-frontend/packages/pipeline-view/node_modules/next/dist/cli/next-dev.js:22:359
做了一些调整,最后得到了这个:
const path = require("path");
const libPath = "../components/src"
const aliasPathsToResolve = [
{ name: "Common", path: path.resolve(__dirname, libPath) }
];
module.exports = {
webpack: (config, { defaultLoaders }) => {
config.module.rules.push({
test: /\.(js|jsx)$/,
include: [path.resolve(__dirname, libPath)],
use: [defaultLoaders.babel]
});
/** Resolve aliases */
aliasPathsToResolve.forEach(module => {
config.resolve.alias[module.name] = module.path;
});
return config
}
};
但是遇到了另一个错误:
export { default as NavBar } from "./NavBar/NavBar"
^^^^^^
SyntaxError: Unexpected token 'export'
at wrapSafe (internal/modules/cjs/loader.js:1055:16)
at Module._compile (internal/modules/cjs/loader.js:1103:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1159:10)
....
这似乎在 #2850 和 #883 之前遇到过。
所以似乎唯一的解决方案是: https :
据我所知,很快就会有 RFC 提出 Next.js 计划如何解决这个问题,但是如果有人现在需要修复它,我已经在 npm 上发布了我的解决方案https://github.com/ zeit/next.js/pull/10098您可以通过将以下内容放入 package.json 来使用它:
"next": "npm:@sheerun/[email protected]",
并遵循next.config.js:
babelIncludeRegexes: [/turf/],
(在我的情况下,我需要使用 babel 预编译所有 turf 文件)
这个问题有什么进展吗?
我使用 next.js 9.2.0,但babelIncludeRegexes
选项不起作用
这个问题有什么进展吗?
next-transpile-modules
正是为了解决这个问题,你试过了吗?
@martpie我正在使用next-transpile-modules
但是,我在尝试构建应用程序时仍然面临以下错误。 我正在使用带有共享代码库的 monorepo。 尝试从像“@myapp/shared/components/componentname.js”这样的共享访问组件。 我正在使用 nextjs 9.x 和自定义next.config.js
。
错误
`
模块解析失败:意外令牌 (12:4)
您可能需要一个合适的加载器来处理此文件类型,目前没有配置加载器来处理此文件。 见 https://webpack.js.org/concepts#loaders
| const Spinner = props => {
| const renderDefaultSpinner = (spinnerClass, { ...others }) => (
>
发生构建错误
错误:> 由于 webpack 错误,构建失败
`
下一个.config.js
const withTM = require('next-transpile-modules')(['<strong i="26">@myapp</strong>']);
module.exports = withPlugins([withTM, withBundleAnalyzer], {
...
}
请帮助我在这里做错了什么。
@raghav1086你能在 repo 上打开一个问题吗? ;) 它会避免这里的人们的噪音。
+1
我有一个src/
为我的项目目录和lib/
的启动器框架,出口一些常见的utils的/包装,我整个重用了几个不同的应用程序nextjs(我的出发点)
当我启动开发服务器时,lib 不会被注意到。 lib/ 中的任何组件都不会通过加载程序并给出错误
我使用了@Lwdthe1解决方案的变体(https://github.com/zeit/next.js/issues/706#issuecomment-569041997)来修复我上面评论中的 src 和 lib 问题。 除了使用config.resolve.modules
而不是循环遍历aliasPathsToResolve
数组之外,基本相同。
webpack: (config, options) => {
config.resolve.modules = [
'./src/',
'./lib/',
'node_modules'
];
config.module.rules.push({
test: /\.(js|jsx)$/,
include: [path.resolve(__dirname, './lib/')],
use: [options.defaultLoaders.babel],
});
现在 lerna、nextjs 和 babel 的工作解决方案是什么?
我试图避免在导入之前预先编译我的库,而且我在这里的每个解决方案都遇到了麻烦。 这是我无法工作的内容:
next-transpile-modules
。next-babel-loader
include
和exclude
规则以通过/失败。@mikestopcontinues next-transpile-modules
使用 TypeScript 为我开箱即用。
@calebmpeterson和@martpie (我看到你了!👀)。 转回插件,问题好像是没有办法引用子模块。 例如,模式 '@mono/components' 将不支持导入 '@mono/components/Div' 或其他任何内容。 并且指定 '@mono/components/Div' 作为模式也不起作用......并不是说我想为每个共享组件都这样做。 我还尝试对正则表达式生成进行逆向工程以创建匹配模式,虽然输出正则表达式有效,但在幕后发生的其他事情并非如此。
理想情况下,我只想指定“@mono”来处理所有事情,并让我的 package.json 成为我的每个应用程序所依赖的唯一真实来源。 同样,为了能够访问子模块,我想避免维护在我的每个库中导入/导出所有内容的索引文件。
回过头来,我相信如果有某种方法可以通过next-babel-loader
传递rootMode: 'upward'
next-babel-loader
,从而使 babel 可以处理转译逻辑,则可以完全解决当前的问题。 也许这会引发其他与 Next 相关的问题,但问题的根源似乎是 Next 与 webpack 和 babel 纠缠在一起的非典型方式。 当然,有办法将babel-loader
与 Next 的附加逻辑分开吗?
只是next-transpile-modules
前面的更新。 我误诊了这个错误。 如果您需要自定义.babelrc
配置,则使用此方法(索引或子模块)无法导入。 自定义设置不会应用于所需的代码。 这又是一个rootMode: 'upward'
问题。
@mikestopcontinues您需要将babel.config.js
(全局配置)与next-transpile-modules
,而不是.babelrc
(本地配置),常见问题解答中对此进行了解释;)
@martpie你不知道我有多尴尬。 在过去的几周里,我不得不把那句话读了十几遍,而且从来没有费心去点击这个问题。 那完全有效。 谢谢!
next-transpile-modules 为我打破了 React。 它现在抛出我使用无效钩子,而我转译了三个示例模块
有人可以重申什么是使转译工作的最佳配置。 我不明白我必须在 babel.config.js 中写什么
@masbaehr在大多数情况下只是将next-transpile-modules
到您的 next.config 设置中
唯一的问题是next-transpile-modules
不支持 Yarn 2 pnp。
最有用的评论
我越认真地使用
next.js
,并围绕它构建了一个丰富的模块库,这个特性就变得越重要。 它正在成为一个真正的 PITA,在我的内部模块中复制 babel 编译步骤。🚀🤖