Jetzt versenden einige von uns NPM-Pakete (insbesondere Komponenten), die in ES2015 geschrieben wurden, ohne sie zu transpilieren.
Das ist eine ziemlich gute Sache, besonders wenn sie in einem Projekt wie Next.js oder CRA (das Transpiling macht) verwendet werden. Sie bieten Vorteile wie:
Aber wir können das jetzt nicht tun , wir ausschließen alles in node_modules von babel transpiling.
Hier also der Lösungsvorschlag.
Wir haben einen Eintrag in next.config.js
, um Module einzuschließen, die durch babel gehen müssen. Sehen:
module.exports = {
transpileModules: [
"my-component",
"redux/src"
]
}
webpack()
?transpileModules
klingt besserWarum ist dies mit der webpack()-Erweiterung nicht möglich?
Ich hoffe du meinst die benutzerdefinierte Webpack-Konfiguration. Das ist machbar. Dieser sitzt aber in einem vorhandenen Loader. Das zu bekommen ist etwas schwieriger.
transpileModules
klingt besser
Fantastisch. Ich werde aktualisieren.
Werden wir Regexps akzeptieren?
Ja. sicher.
Hey,
Während ich meine eigene Website starte, probiere ich neue Technologien wie Lerna/Next/Styled... aus und gebe gerne frühzeitig Feedback dazu.
Ich habe ein doppeltes Problem geöffnet
Mir ist auch aufgefallen, dass Babel, das ebenfalls auf Lerna basiert, jedes Modul transpiliert , bevor es veröffentlicht wird, aber es @arunoda vorschlägt und die Client-App die Transpilierung durchführen zu lassen.
Ich möchte eine einzelne Babel-Konfiguration für meinen Client haben und diese Konfiguration mit allen meinen entkoppelten Modulen teilen. Das ist wahrscheinlich nicht so einfach, wenn ich die Möglichkeit haben möchte, meine Module als Standalone außerhalb von Next Runner auszuführen
Mein aktuelles Testprojekt ist hier: https://github.com/slorber/playground/ Ich werde versuchen, es zu aktualisieren, sobald es einen Fork/PR gibt. @arunoda arbeitest du daran?
@slorber derzeit konzentrieren wir uns auf die Veröffentlichung von 2.0 und wir
Ich habe noch nicht damit begonnen, aber wir können dies kurz nach 2.0 tun.
Okay, ich mache eine Gabel. Ich laufe bereits gegen 2.0.0 Beta, weil ich keine kritische Website erstelle und ich glaube nicht, dass Webpack 1.13 das Feld jsnext:main/module auflöst .
Ich bin kein Bundler-Experte, aber ich denke, ich würde eher das Feld "module" von package.json verwenden, nein? "main" scheint für bereits transpilierten Code zu sein, soweit ich weiß. Aber da die Webpack-Konfiguration es ermöglicht, die Transpilation einzuschließen/auszuschließen, bin ich mir nicht sicher, ob dies relevant ist. Irgendeine Empfehlung, welches der 3 Felder ich lieber verwenden würde?
@slorber Ich denke, Webpack unterstützt nur main
genau wie NPM. Das kannst du benutzen.
Wir können den Dateipfad in der Funktion exclude
in unserem next.conf.js
überprüfen
Hmm nach dem, was ich in der Praxis gegen Next 2.x gesehen habe, habe ich gesehen, dass das Modul funktioniert (aber später zur Laufzeit fehlschlägt, weil es nicht transpiliert wurde), während jsnext:main nicht funktionierte (soweit ich mich erinnere). Aber es soll unterstützt werden .
Wie auch immer, jsnext:main oder module scheint nicht die Lösung für dieses Problem zu sein, daher reicht es für firmeninterne Module wahrscheinlich aus, die Transpilation zu aktivieren
Die Community hat sich nicht auf einen Ansatz geeinigt, oder? Zum Beispiel konnte ich react-youtube
das andere ohne Probleme verwenden. Ich gehe davon aus, dass eine große Anzahl von Modulen vor der Veröffentlichung transpiliert werden?
Ref: https://github.com/rauchg/blog/blob/master/components/post/youtube.js
Ja, es ist sinnvoll, immer vor der Veröffentlichung zu transpilieren, da Sie nicht wissen, wer/wie das Modul konsumiert wird und Sie den Client nicht zwingen möchten, geeignete Babel-Einstellungen für Ihre Lib einzurichten. Das ist es, was Rollup vorschlägt : das Modul auf verschiedene Weise
Bei unternehmensinternen Paketen können die Transpilationseinstellungen jedoch über mehrere Projekte hinweg gleich sein (wie ein Babel-Preset) und es ist für mich sinnvoll, den Client-Bundler alle Unternehmensabhängigkeiten transpilieren zu lassen
Stimme sehr zu aufteilen und die Dinge so weit wie möglich isolieren.
Und @rauchg / @arunoda, die RegExp's unterstützen, wäre wirklich nett, also könnten Sie einen Eintrag haben, der alle firmeninternen Module
// next.config.js
module.exports = {
transpileModules: [
/^\@my-npm-org\/.*/
]
}
Schöner Vorschlag @philcockfield
Hey, vielleicht könnte es sich lohnen, ein paar Presets anzubieten. Es scheint mir, dass die meisten Tools (Lerna / npm-Link ...) auf Symlinks basieren, warum also nicht etwas so Einfaches wie:
```javascript
module.exports = {
transpileModules: ["symlinks"]
}
````
Je mehr ich next.js
ernsthaft nutze und eine reichhaltige Bibliothek von Modulen drumherum erstelle, desto wichtiger wird diese Funktion. Es wird zu einem echten PITA, das den Babel-Kompilierungsschritt in meinen internen Modulen repliziert.
🚀🤖
Daran arbeite ich heute :)
@philcockfield probiere das mal aus: https://github.com/zeit/next.js/pull/749
danke @arunoda
Wie in Ihrem PR kommentiert, ist die Funktion etwas eingeschränkt, wenn dies keine Symlinks unterstützt, da sie nicht mit npm-Link oder Lerna funktioniert, sondern nur für npm-Module, die nicht transpiliert sind (richtig? Ich sehe keine anderen?) Anwendungsfall, es sei denn, Sie übertragen Module innerhalb von /node_modules
)
Warum keine Symlinks unterstützen? ist es schwieriger zu unterstützen?
Außerdem wollte ich Ihren Zweig in meiner App testen, bin mir aber nicht sicher, wie das am besten geht. Gibt es ein bekanntes Verfahren, mit dem wir einen Zweig einfach testen können und es für den Tester nicht zu schmerzhaft ist? Ich habe einiges ausprobiert wie:
Wie testet man derzeit eine Gabel am besten?
Wenn Sie dies mit next.config.js
: module.exports = { webpack: (config
, dann hat config.module.rules
ein paar Dinge. Sie müssen eine dieser Regeln ändern oder hinzufügen? :
{ 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: [] } } ]
Ich freue mich auf die vorgeschlagene einfachere Syntax.
Entschuldigung für meine Unwissenheit, ich kann nicht sehen, was die Lösung dieses Problems ist? Wir würden gerne es6 in unsere Codebasis importieren, wir brauchen das Tree-Shaking .
Gibt es dazu eine PR?
@andrewmclagan Dieses Problem ist noch offen und hat eine verwandte PR , die wahrscheinlich nicht alle zufriedenstellen wird (wie LernaJS-Benutzer)
Wie ist der Stand davon? Gibt es andere Möglichkeiten, das Webpack von next so zu gestalten, dass aus node_modules importierte Dateien transpiliert werden?
@slorber ich
ich stehe vor einem ähnlichen Problem. Es wird versucht, das Paket get-urls
. Funktioniert mit dev
aber wenn ich es kompiliere. Ich habe einen Fehler von uglify erhalten
...
{ Error: commons.js from UglifyJs
...
Gibt es hierfür bitte einen Workaround?
Arunoda wird hier irgendwann daran arbeiten. Hat er schon in #749 gemacht
Ich würde diese Funktion gerne implementiert sehen. Wie @philcockfield erwähnte, ist es ein übliches Szenario, eine Bibliothek von Modulen aufzubauen, die von der Next.js-Transpilation abhängig sind, und es wäre großartig, Komponenten zwischen Projekten teilen zu können.
Dies wird nicht nur beim Baumrütteln benötigt. Auch für Babel-Plugins wie styled-jsx
. Wenn Sie also ein Modul (wie eine Bibliothek) haben, das ein Babel-Plugin verwendet, besteht die beste Lösung darin, den ES6-Quellcode einzubinden und Ihrer App zu erlauben, ihn aus node_modules zu transpilieren. Natürlich enthält next standardmäßig bereits styled-jsx
.
Folgendes habe ich getan
// 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);
Ich habe im Grunde jedes exclude
durch eine benutzerdefinierte Funktion ersetzt.
Ich weiß nicht, was ich falsch mache, aber ich kann es einfach nicht zum Laufen bringen.
Ich muss den Inhalt von node_modules/mycomponents
auch von Next.js transpilieren
Es funktioniert nicht einmal, wenn ich alle Ausschlüsse mit einem leeren Array vollständig überschreibe
exports.webpack = config => (config.module.rules = config.module.rules.map(({exclude, ...rest}) => ({
exclude: [],
...rest
})), config);
Bitte hilf mir :)
Vielen Dank
Hey Leute ( @thealjey ) Ich jsnext:main
betriebene Module.
jsnext:main
in package.json ist, transpiliere den angegebenen Einstiegspunkt, andernfalls importiere, was in main
Ich benutze nicht next.js
aber ich hoffe, es hilft.
@damianobarbati nein, leider nicht
Webpack direkt zu konfigurieren, um alles zu transpilieren, ist nicht schwierig, aber ich habe Mühe, dies im Kontext von Next.js zum Laufen zu bringen
Hallo zusammen, hat jemand eine Lösung gefunden?
Ich habe ein lokales ES6-Linked-Node-Modul, das ich in mein Projekt importieren muss, aber ich kann das Webpack-Voodoo nicht richtig hinbekommen!
Ich bin sicher, es gibt einen besseren Weg, aber wir führen alles durch babel beim Build:
next build && babel .next/*.js --out-dir . --presets=es2015,react
Ist das gestorben? Ich suche nach einer Möglichkeit, ein benutzerdefiniertes Modul zu transpilieren, und es scheint, als wäre dies immer noch nicht möglich.
@mattfelten es steht auf der Roadmap für v5
Hat jemand ein Beispiel für einen Workaround dafür?
@timneutkens Gibt es dafür eine Zeitleiste? Schätzen Sie, dass dies oft eine unmögliche Frage ist, aber wir versuchen, unseren Stack bei der Arbeit zu bestimmen, und dies ist ein ziemlich großer Blocker für uns! :)
Vorschläge zur Problemumgehung sind ebenfalls gültig.
@thealjey ist sich include
angegeben ist, das überschrieben werden müsste.
Update: Diese Strategie wurde geprüft, aber angesichts all der verschiedenen Loader für verschiedene Modulverzeichnisse in der internen Konfiguration von next.js ist sie einfach nicht vernünftig. Das muss erstklassig sein.
@chrisui meine (vorläufige) Lösung bestand darin, babel-plugin-module-resolver zu verwenden , konfiguriert wie folgt - "plugins": [["module-resolver", {"root": ["./"]}]]
es ist keineswegs eine perfekte lösung, aber da alles andere fehlgeschlagen ist, funktioniert es vorerst
dadurch muss ich nicht bei jedem Import einen Haufen ../
schreiben
Dies könnte für einige tatsächlich eine bessere Lösung sein, obwohl es bei der Wiederverwendbarkeit sicherlich nicht hilft
@thealjey könntest du ein Beispiel geben?
Ich habe ein Projekt-Setup, bei dem ich dies vergeblich versuche ...
https://github.com/jamesgorrie/nappy
Ich würde gerne versuchen, eine PR zu bekommen, da dies unser Leben so viel einfacher machen würde, aber es gibt ein paar Fragen wie: Sollte next.js
das Transpilieren bestimmter Module unterstützen oder sollte dies dem Transpiler überlassen werden, aber die next.js
folgt strenger der Modulauflösung. Ich bin mir nicht sicher, wen Sie fragen oder wo Sie hier als Neuling bei next.js
anfangen sollen.
es ist auf der Roadmap für v5
@timneutkens hat es das in v5 geschafft?
frage mich zu wissen.
Schauen Sie sich nur an, wo es zusammengeführt wurde. Dies wurde vor 8 Tagen zusammengeführt. 5.0.0 wurde vor 2 Tagen veröffentlicht. von der kanarischen Filiale, wo diese in...
Hat jemand ein Beispiel, wie das umgesetzt werden kann? Soll das wie oben beschrieben so funktionieren?
module.exports = {
transpileModules: ['my-npm-module']
}
oder sieht es anders aus?
Ich bin verwirrt. @timneutkens Der oben genannte Link führt zu einer noch offenen PR. Wurde dies noch NICHT in v5 zusammengeführt?
EDIT: Egal, dies ist nur eine PR, um das Beispiel hervorzuheben.
Es ist ein Beispiel, Sie können das Beispiel verwenden, ohne dass es zusammengeführt wird. transpileModules
ist etwas, das wir später in Angriff nehmen werden.
Als Faustregel gilt: Wenn ein Issue geöffnet ist, wird es nicht freigegeben.
@brianyingling Ich habe das Beispiel in ein Plugin für eine Zwischenlösung umgewandelt (nur v5).
Im Moment funktioniert es für uns, bis die robustere, offizielle Lösung eingeführt ist.
https://www.npmjs.com/package/@weco/next -plugin-transpile-modules
Ich würde gerne ein Beispiel dafür für ein einzelnes Modul in der Anwendungscodebasis sehen.
Zum Beispiel habe ich ein Modul, das ich sowohl server- als auch clientseitig verwende. Ich konnte keines der obigen Beispiele zum Laufen bringen, entweder indem ich das Modul in ein eigenes separates Modul einbezog und es yarn link
ing, oder indem ich die Webpack-Regeln hackte.
Hier ist ein einfaches Repro: https://github.com/statico/nextjs-with-async-lib
// 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 sagt mir, dass dies daran liegt, dass ich async/await
im freigegebenen Modul verwende. Ich denke, meine Lösung könnte darin bestehen, async/await zu entfernen und alles in .then()
-Rückrufe zu ändern.
OK, ich habe eine Lösung gefunden, die für mich funktioniert.
Zuerst habe ich die Einstellung config.resolve.symlinks = false
zu meiner next.config.js
Konfiguration pro https://github.com/zeit/next.js/issues/3018#issuecomment -380879576 hinzugefügt
// next.config.js
webpack: (config, { dev }) => {
config.resolve.symlinks = false
return config
}
Dann lege ich meine gemeinsame Bibliothek – eine .js
Datei, die CommonJS-Exporte und async
/ await
-Schlüsselwörter verwendet – in ein Unterverzeichnis der Anwendung namens 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": { ... }
}
Und schließlich habe ich ein postinstall
Skript hinzugefügt, um alles miteinander zu verknüpfen, wenn jemand ein yarn install
in der Hauptanwendung macht:
// package.json
{
...
"scripts": {
"postinstall": "cd shared ; yarn -s unlink ; yarn link && yarn && cd .. && yarn link @myapp/shared",
...
Jetzt laufen meine Mocha-Tests auf der Serverseite, mein benutzerdefinierter Koa-Server startet gut und es gibt keine verrückten Cannot assign to read only property 'exports' of object '#<Object>'
auf meinen NextJS-Seiten.
Ich hatte das gleiche Problem beim Upgrade auf NextJs 5.1.0. Ein oder zwei der Knotenmodule im nächsten transpilierten keine Fettpfeilfunktionen und warfen Fehler in IE11. Ich hatte zuvor einzelne Polyfills eingerichtet und am Ende entschied ich mich, diese Moduldateien mit babel-polyfill
in meinem next.config.js
mit diesem Ziel zu erreichen:
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 })
}
}
Hoffe das hilft jemandem.
ESM funktioniert wie ein Zauber.
Mit einem benutzerdefinierten Next.js-Server in index.js
kann ich diesen Befehl ausführen, um den Server zu starten, und esm startet perfekt und löst ES-Module in Lerna-symlinked Projektpaketen auf.
node -r esm index.js
@curran cool, kann es babel-node ersetzen?
@curran Das würde ich in der Produktion vermeiden
@blackbing ich weiß es nicht.
@thealjey Warum ist das so?
Falls jemand nach einer schnellen und einfachen Lösung sucht, habe ich Folgendes getan. Ich habe ein Unterverzeichnis, shared/
, mit jedem Code erstellt, den wir sowohl auf dem Backend über ein eigenständiges Node-Skript als auch auf dem Client über NextJS ausführen möchten. Es hat sein eigenes package.json
und deklariert seinen Namen als @myproject/shared
.
Dann habe ich im Haupt-(übergeordneten) Projekt ein Postinstall-Skript wie folgt zu package.json
hinzugefügt: cd shared && yarn -s unlink >/dev/null 2>&1 ; yarn -s link && yarn -s && yarn link @myproject/shared
— dann führe yarn
mindestens einmal aus und ändere deine Importe in import { whatever } from '@myproject/shared/somefile'
Auf diese Weise funktioniert der freigegebene Code ohne verrückte Transpilationsschritte und Sie müssen yarn
/ npm
jedes Mal erneut ausführen, wenn Sie ein Update vornehmen, da yarn link
ein Symlink.
Für diejenigen, die TypeScript verwenden, sollte @weco/next-plugin-transpile-modules
nicht funktionieren. Ich habe einen Fork erstellt, um Nexts withTypescript
: https://github.com/KeitIG/next-plugin-transpile-modules
Ich muss jedoch noch herausfinden, wie man die Dinge richtig macht, wenn wir auch serverseitigen Code in TypeScript benötigen.
Gibt es darüber irgendwelche Neuigkeiten?
@bogdansoare Ich verwende https://github.com/KeitIG/next-plugin-transpile-modules
Und noch eins von mir, im folgenden Kern. Es verarbeitet TypeScript und auch bestimmte Pakete eines @scope
, und nicht alle Pakete. https://gist.github.com/trusktr/44400d0d016c506629b4f914799dc9cd
Ich habe gerade ein einfaches Arbeitsbeispiel zusammengestellt, das esm
und lerna
https://github.com/curran/nextjs-esm-beispiel
/cc @jdalton
Ich persönlich habe das mit den folgenden next.config.js
:
module.exports = {
webpack: (config, options) => {
config.module.rules.push({
test: /\.js$/,
include: /node_modules/,
use: [
options.defaultLoaders.babel
]
})
return config
}
}
Es babelt alles in node_modules
, was ich brauchte, um IE 11-Kompatibilität zu erreichen...
Ich würde mich auch über eine Lösung dafür freuen, da ich damit zu kämpfen habe, meinem Projekt nicht transpilierte npm-Pakete hinzuzufügen. Musste sie vorerst auf Vendor/ herunterladen :(
Wirklich nervig
@bel0v Ich glaube, Sie sollten dies bereits mit next-plugin-transpile-modules
. Dieses Problem sollte wahrscheinlich geschlossen werden. cc/ @timneutkens
Ich würde trotzdem gerne nach alternativen Lösungen suchen.
Kürzlich hat Jamie einen sehr ausführlichen Thread zum Thema Kompilieren von node_modules geschrieben: https://twitter.com/jamiebuilds/status/1080840492525350912
Ich habe den Thread von Jamie gelesen, möchte aber auch Henry Zhu und Babels Meinung zu dieser Situation und Lösung teilen.
https://babeljs.io/blog/2018/06/26/on-consuming-and-publishing-es2015+-packages
(Ich bin nicht anderer Meinung mit Tim, dachte nur, ich würde sagen, viele Vor- und Nachteile. Könnte Tim bei der Untersuchung alternativer Lösungen helfen)
Ja, wir haben im letzten halben Jahr mit vielen Leuten über dieses Thema gesprochen, darunter auch Henry 😄
Ungeachtet der Bedenken hinsichtlich des Transpilierens von node_modules ist der Wunsch, eigene Pakete in einem Monorepo zu transpilieren, eine sehr häufige Anforderung, auf die diese Bedenken nicht zutreffen
@dcalhoun Ich habe es versucht, aber leider erhalte ich immer noch einen unerwarteten Token-Fehler. Es gibt ein offenes Next 7-Problem bei diesem Plugin, das möglicherweise damit zusammenhängt
@bel0v
Du solltest die FAQ lesen ;) für dieses Problem gibt es eine Lösung: https://github.com/martpie/next-plugin-transpile-modules#i -have-trouble-making-it-work-with-nextjs-7
Ich habe dieses Plugin in mehreren Projekten verwendet und es erledigt die Arbeit gut. Das Next 7 Issue ist seltsam, ich bin mir nicht sicher, ob das von Next oder Babel kommt, ich habe trotzdem ein Issue hier eröffnet: https://github.com/zeit/next.js/issues/5393
@martpie ja, ich glaube, das habe ich versucht.. ich werde es auf jeden Fall noch einmal versuchen
@martpie wir haben begonnen, next7 mit einer konsistenten babel.config.js und Garn-Arbeitsbereichen zu verwenden, ich könnte sehen, ob ich ein einfaches Beispiel einrichten kann.
Ich habe hier ein einfaches Beispiel gegabelt
https://github.com/bel0v/learnnextjs-demo
darin installierte ich eine nicht transpilierte Abhängigkeit (wired-elements), bekam einen Build-Fehler Unhandled Rejection (SyntaxError): Unexpected token {
und versuchte, den vorgeschlagenen Weg zu beheben.
Ich denke, vielleicht brauche ich ein paar zusätzliche Babel-Plugins, damit es funktioniert.. 🤔
@bel0v in den FAQ gibt es erneut eine Erklärung, warum Lerna-Setups nicht funktionieren (TL, DR; Sie verwenden wahrscheinlich falsch)
@martpie ah, verstanden! Wusste nicht, dass das Drittanbieterpaket mit Lerna eingerichtet wurde. Vielen Dank
Anscheinend wurde https://twitter.com/jamiebuilds gesperrt, daher kann der Thread dort nicht mehr gelesen werden. #3018 Wurde in Bezug auf dieses Problem geschlossen, also frage ich mich, welche alternativen Ansätze in Betracht gezogen werden?
Stellen diese den Stand der Technik / Best Practices von next.js für diese Anwendungsfälle atm dar?
https://github.com/curran/nextjs-esm-beispiel
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
Wenn Sie also wie ich an einem Projekt arbeiten, das IE11 unterstützen muss, müssen Sie wirklich den gesamten Code in node_modules/
transpilieren. In Next.js 7.x habe ich das folgende Setup verwendet, das großartig funktioniert hat.
Leider funktionierte es in Next.js 8.x nicht mehr mit Fehlern, dass Module andere Module nicht importieren konnten, weil sie keinen Standardexport hatten. Ich habe dann die folgende Konfiguration für Next.js 8.x entwickelt, die nur den Code in node_modules/
mit @babel/preset-env
transpiliert und keine anderen Plugins.
Dies wird kombiniert, indem ich meine browserlist
Eigenschaft in der package.json
-Eigenschaft
"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
},
}
Leider habe ich noch nicht herausgefunden, wie man @babel/plugin-transform-runtime
mit diesem Setup verwendet, daher wird es wahrscheinlich einige Helfer im Code ausspucken 😞 hoffentlich kümmert sich gzip darum 😆 😅
Ich denke, es wäre großartig, wenn Next.js uns eine Option geben könnte, um node_modules/
korrekt zu transpilieren, um mit allen browserlist
Sie haben. Es scheint, als ob alle großen Websites mit Unternehmensbenutzern davon abhängig sind, um ältere Browser ordnungsgemäß zu unterstützen.
Als Betreuer von next-transpile-modules
(basierend auf der großartigen Arbeit von @jamesgorrie) helfe ich gerne jedem, der hier mit diesem Problem konfrontiert ist.
Ich arbeite seit mehr als einem Jahr an professionellen Projekten mit diesem Plugin und bisher hat es gut gespielt.
Nativer Support von Next.js wäre natürlich super und ich helfe gerne bei der Integration dieses Features in das next
Paket. Ich weiß, dass Tim einige Ideen hatte, die er ausprobieren wollte, aber trotzdem.
Danke schön!
@martpie Ich
Außerdem sehe ich, dass Sie options.defaultLoaders.babel
auswählen und das als Babel-Loader verwenden. Bei Next.js 8.x hatte ich das Problem, dass einige Module danach nicht richtig als CJS-Modul erkannt wurden und andere Libs sie nicht importieren konnten, zB:
./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'.
Aus diesem Grund habe ich eine benutzerdefinierte Babel-Konfiguration für node_modules/
bereitgestellt, die den Code nur mit preset-env
transpiliert und die Next.js-spezifischen Transformationen überspringt. Was halten Sie von diesem Ansatz?
Prost 🍻
@LinusU Vielleicht versuchen Sie es mit transpileModules: ['(.*?)']
und sagen Sie mir, ob es funktioniert?
Aber es kann sein, dass es in einer zukünftigen Hauptversion nicht funktioniert, also seien Sie vorsichtig.
Im Allgemeinen empfehle ich nicht (lesen Sie "sehr entmutigt"), den gesamten node_modules
Ordner zu transpilieren, das Kompilieren dauert ewig und Pakete sollten ES3-kompatiblen Code enthalten (also IE11-kompatibel).
Transpilieren Sie nur das Modul, das Sie benötigen! (wie lodash-es
, lokale Module etc...)
Pakete sollten ES3-kompatiblen Code bereitstellen (also IE11-kompatibel).
Dies ist jedoch nicht die Realität, die ich gesehen habe, und ich stimme tatsächlich nicht zu. Die Modulautoren werden nie genau wissen, welche Browser ich anvisiere, und wenn sie älteren Code ausliefern, werden sie potenziell Benutzer bestrafen, die auf moderne Browser abzielen.
das kompilieren dauert ewig
Es ist beim Start etwas langsam für mich, aber danach scheint es zwischengespeichert zu werden und wenn ich Änderungen an einer bestimmten Seite vornehme, sehe ich fast sofortige Neuladevorgänge.
Transpilieren Sie nur das Modul, das Sie benötigen!
Dazu müsste ich genau wissen, welche Pakete mit IE11 kompatibel sind und welche nicht, und diese Informationen immer auf dem neuesten Stand halten, wenn sich Abhängigkeiten (auch vorübergehende Abhängigkeiten) ändern. Ich sehe nicht, wie das realistisch ist
Wichtig ist, dass ESM-Einstiegspunkte, die in package.json module
bereitgestellt werden, normalerweise ES5 mit ES6-Importen/Exporten für Tree Shaking sind. Dies ist also die Aufgabe eines Bundlers (Webpack) und nicht eines Transpilers (Babel), sofern nicht anders angegeben. Viele gut gepflegte Pakete haben bereits ESM-Einstiegspunkte, zB redux/es
für Redux, das von OP erwähnt wurde.
Wenn Sie dies mit
next.config.js
:module.exports = { webpack: (config
, dann hatconfig.module.rules
ein paar Dinge. Sie müssen eine dieser Regeln ändern oder hinzufügen? :{ 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: [] } } ]
Ich freue mich auf die vorgeschlagene einfachere Syntax.
Funktioniert bei mir gut
{
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']
}
},
Ich stieß auf dieses Problem mit einem Lerna-Mono-Repo und kratzte mich am Kopf, was die Ursache war. Da der Fehler von Webpack kommt, gibt es keine guten Details, abgesehen davon, dass ein Loader fehlt, was nicht hilfreich ist. Zum Glück habe ich dieses Github-Problem gefunden!
Ich werde meine Lösung hier für alle anderen lassen, die nach diesem Problem suchen und auch Lerna verwenden:
Erstellen Sie ein Prepublish-Skript für das freigegebene Paket, das die Quelle in ein Verzeichnis dist transpiliert, und weisen Sie Lerna an, beim Verknüpfen auf das Verzeichnis dist zu verweisen:
// 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"
}
Wenn Sie jetzt lerna bootstrap
ausführen, wird das Prepublish-Skript ausgeführt und die Quelle transpiliert, damit Next sie verwenden kann.
Wenn Sie lerna
, können Sie Symlinks erstellen, um mit next-transpile-modules transpiliert zu werden . Wie Sie dieses Paket mit lerna
steht am Ende der Dokumentation.
Für alle, die nach dem Teilen von Code für NextJs-Apps suchen, möchte ich nur berichten, dass die Lösung von @LinusU für mich funktioniert hat, als ich versucht habe, React-Komponenten und -Utils zwischen mehreren NextJs-Apps in meinem Mono-Repo zu teilen:
// 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
})
}
}
}
Ich verwende die neueste Version von NextJs zum Zeitpunkt dieses Beitrags.
@Lwdthe1 Ich habe Ihren Code ausprobiert und zunächst diesen Fehler erhalten:
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
Habe etwas nachgebessert und bin dabei auf folgendes gekommen:
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
}
};
Aber es ist ein anderer Fehler aufgetreten:
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)
....
die anscheinend schon einmal in #2850 und #883 konfrontiert wurde.
Es scheint also die einzige Lösung zu sein: https://github.com/martpie/next-transpile-modules#but -i-really-need-to-make-it-work-with-lerna
Nach allem, was ich gehört habe, wird RFC bald vorgestellt, wie Next.js dieses Problem lösen will, aber wenn jemand es jetzt beheben muss, habe ich auf npm meine Lösung von https://github.com/ veröffentlicht. zeit/next.js/pull/10098, die Sie verwenden können, indem Sie Folgendes in package.json einfügen:
"next": "npm:@sheerun/[email protected]",
und folgendes zu next.config.js:
babelIncludeRegexes: [/turf/],
(in meinem Fall musste ich alle Rasendateien mit Babel vorkompilieren)
Hat dieses Problem Fortschritte?
Ich verwende next.js 9.2.0, aber die Option babelIncludeRegexes
funktioniert nicht
Hat dieses Problem Fortschritte?
next-transpile-modules
zielt darauf ab, dieses Problem genau zu lösen, hast du es versucht?
Hallo @martpie ,
Lösen Sie bereits mein Problem mit der Bearbeitung der .babelrc-Datei. Ich verweise auf dieses Problem
Danke
@martpie Ich verwende next-transpile-modules
aber trotzdem wird der folgende Fehler angezeigt , während ich versuche, die Anwendung zu erstellen. Ich verwende Monorepo mit gemeinsamer Codebasis. Es wird versucht, von freigegebenen Komponenten wie "@myapp/shared/components/componentname.js" auf Komponenten zuzugreifen. Ich verwende nextjs 9.x und benutzerdefinierte next.config.js
.
Fehler
`
Modulparsen fehlgeschlagen: Unerwartetes Token (12:4)
Möglicherweise benötigen Sie einen geeigneten Loader, um diesen Dateityp zu verarbeiten. Derzeit sind keine Loader für die Verarbeitung dieser Datei konfiguriert. Siehe https://webpack.js.org/concepts#loaders
| const Spinner = Requisiten => {
| const renderDefaultSpinner = (spinnerClass, { ...others }) => (
>
Build-Fehler aufgetreten
Fehler: > Build aufgrund von Webpack-Fehlern fehlgeschlagen
`
next.config.js
const withTM = require('next-transpile-modules')(['<strong i="26">@myapp</strong>']);
module.exports = withPlugins([withTM, withBundleAnalyzer], {
...
}
Bitte helft mir was ich hier falsch mache.
@raghav1086 Können Sie ein Problem im Repo öffnen? ;) Es wird Lärm für die Leute hier draußen vermeiden.
+1
Ich habe ein src/
Verzeichnis für mein Projekt und lib/
für ein Starter-Framework, das einige gängige Utils/Wrapper exportiert, die ich in einigen verschiedenen nextjs-Apps wiederverwende (mein Ausgangspunkt)
lib wird nicht bemerkt, wenn ich den Dev-Server starte. Alle Komponenten von lib/ durchlaufen den Loader nicht und geben einen Fehler aus
Ich habe eine Variante der Lösung von @Lwdthe1 (https://github.com/zeit/next.js/issues/706#issuecomment-569041997) verwendet, um das src- und lib-Problem in meinem obigen Kommentar zu beheben. Im Grunde dasselbe, außer dass config.resolve.modules
anstatt das Array aliasPathsToResolve
durchlaufen.
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],
});
Was ist heutzutage die funktionierende Lösung für lerna, nextjs und babel?
Ich versuche zu vermeiden, meine Bibliotheken vor dem Importieren vorab zu transpilieren, und bin hier mit jeder Lösung gegen eine Mauer gestoßen. Folgendes kann ich nicht zum Laufen bringen:
next-transpile-modules
.next-babel-loader
include
und exclude
auf bestanden/nicht bestanden.@mikestopcontinues next-transpile-modules
für mich mit TypeScript sofort funktioniert.
@calebmpeterson und @martpie (Ich sehe dich! 👀). Ich ging zurück zum Stecker, und das Problem scheint zu sein, dass es keine Möglichkeit gibt, auf Submodule zu verweisen. Zum Beispiel unterstützt das Muster '@mono/components' den Import von '@mono/components/Div' oder was auch immer nicht. Und die Angabe von '@mono/components/Div' als Muster funktioniert auch nicht ... nicht, dass ich das für jede gemeinsam genutzte Komponente tun möchte. Ich habe auch versucht, die Regex-Generierung rückzuentwickeln, um Übereinstimmungsmuster zu erstellen, und während die Ausgabe von Regex funktioniert, passiert etwas anderes unter der Haube, das nicht funktioniert.
Im Idealfall würde ich einfach '@mono' angeben, um sich um alles zu kümmern, und meine package.json als einzige Quelle der Wahrheit für das, wovon jede meiner Apps abhängt, belassen. Ebenso möchte ich es vermeiden, Indexdateien zu verwalten, die alles in jede einzelne meiner Libs importieren/exportieren, nur um auf Untermodule zugreifen zu können.
Um zurück zu kehren, ich glaube, das aktuelle Problem könnte vollständig gelöst werden, wenn es eine Möglichkeit gäbe, rootMode: 'upward'
durch next-babel-loader
, damit Babel die Transpilierungslogik handhaben könnte. Vielleicht eröffnet dies andere Next-bezogene Probleme, aber die Wurzel des Problems scheint die untypische Art und Weise zu sein, wie Next in Webpack und Babel verwickelt ist. Sicherlich gibt es eine Möglichkeit, babel-loader
von der zusätzlichen Logik von Next zu trennen?
Nur ein Update zur next-transpile-modules
Front. Ich hatte den Fehler falsch diagnostiziert. Mit dieser Methode (Index oder Submodul) funktioniert kein Import, wenn Sie eine benutzerdefinierte .babelrc
Konfiguration benötigen. Die benutzerdefinierten Einstellungen werden einfach nicht auf den erforderlichen Code angewendet. Dies ist wieder ein rootMode: 'upward'
Problem.
@mikestopcontinues Du musst babel.config.js
(globale Konfiguration) mit next-transpile-modules
und nicht .babelrc
(lokale Konfiguration), es wird in der FAQ erklärt ;)
@martpie Du hast keine Ahnung, wie peinlich ich bin. Ich musste diese Zeile in den letzten Wochen ein Dutzend Mal gelesen haben und habe mich nie die Mühe gemacht, mich bis zum Thema durchzuklicken. Das hat total funktioniert. Vielen Dank!
next-transpile-modules hat React für mich kaputt gemacht. Es wirft jetzt aus, dass ich ungültige Hooks verwende, während ich DREI Beispielmodule transpiliert habe
Könnte jemand wiederholen, was die beste Konfiguration ist, um die Transpilation zum Laufen zu bringen. Ich verstehe nicht, was ich in babel.config.js schreiben muss
@masbaehr fügt in den meisten Fällen einfach next-transpile-modules
zu Ihrem next.config-Setup hinzu
Das einzige Problem ist, dass next-transpile-modules
Yarn 2 pnp nicht unterstützt.
Hilfreichster Kommentar
Je mehr ich
next.js
ernsthaft nutze und eine reichhaltige Bibliothek von Modulen drumherum erstelle, desto wichtiger wird diese Funktion. Es wird zu einem echten PITA, das den Babel-Kompilierungsschritt in meinen internen Modulen repliziert.🚀🤖