Next.js: Tambahkan dukungan ke modul transpile di dalam node_modules

Dibuat pada 9 Jan 2017  ·  103Komentar  ·  Sumber: vercel/next.js

Sekarang beberapa dari kita mengirimkan paket NPM (khususnya komponen) yang ditulis dalam ES2015 tanpa mengubahnya.

Itu hal yang cukup bagus khususnya jika mereka akan digunakan dalam proyek seperti Next.js atau CRA (yang melakukan transpiling). Mereka menawarkan manfaat seperti:

  • Tidak perlu transpile sebelum dikirim ke NPM
  • Dapatkan manfaat dari goyangan pohon Webpack 2

Tapi kita tidak bisa melakukan ini sekarang kita mengecualikan semua yang ada di dalam node_modules dari babel transpiling.

Jadi, inilah solusi yang diusulkan.

Kami memiliki entri di next.config.js untuk menyertakan modul yang harus melalui babel. Lihat:

module.exports = {
   transpileModules: [
     "my-component",
     "redux/src"
   ]
}
story feature request

Komentar yang paling membantu

Semakin saya menggunakan next.js dengan sungguh-sungguh, dan membangun perpustakaan modul yang kaya di sekitarnya, semakin penting fitur ini. Ini menjadi PITA nyata yang mereplikasi langkah kompilasi babel di modul internal saya.

🚀🤖

Semua 103 komentar

  • Mengapa ini tidak dapat dilakukan dengan ekstensi webpack() ?
  • transpileModules terdengar lebih baik
  • Apakah kami akan menerima regexps?

Mengapa ini tidak dapat dilakukan dengan ekstensi webpack()?

Saya harap maksud Anda konfigurasi webpack khusus. Itu bisa dilakukan. Tapi ini duduk di loader yang ada. Mendapatkan itu agak sulit.

transpileModules terdengar lebih baik

Luar biasa. saya akan memperbarui.

Apakah kami akan menerima regexps?
Ya. Tentu.

Hai,

Saat saya memulai situs web saya sendiri, saya mencoba teknologi baru seperti Lerna/Berikutnya/Bergaya... dan dengan senang hati akan memberikan umpan balik awal tentang ini.

Saya telah membuka masalah duplikat di mana saya mencoba mengimpor/mengubah modul berbasis CRA di modul NextJs saya tetapi tidak tahu bagaimana membuat transpilasi terjadi (perhatikan bahwa saya ingin modul saya tetap dapat dijalankan sebagai mandiri)

Saya juga memperhatikan bahwa Babel, juga berdasarkan Lerna, mentranspilasikan setiap modul sebelum mengeksposnya, tetapi menurut saya lebih baik melakukan seperti yang disarankan @arunoda dan membiarkan aplikasi klien melakukan transpiling.

Saya ingin memiliki satu konfigurasi babel untuk klien saya dan membagikan konfigurasi itu dengan semua modul saya yang dipisahkan. Itu mungkin tidak begitu mudah jika saya ingin menjaga kemampuan untuk menjalankan modul saya sebagai standalone, di luar Next runner

Proyek pengujian saya saat ini ada di sini: https://github.com/slorber/playground/ Saya akan mencoba memutakhirkannya segera setelah ada garpu/PR. @arunoda apakah Anda sedang mengerjakannya?

@slorber saat ini kami fokus pada rilis 2.0 dan kami menyempurnakan hal-hal dan menemukan bug sebanyak mungkin.

Saya belum mulai mengerjakan ini tapi kita bisa melakukannya setelah 2.0.

Ok jadi saya akan membuat garpu. Saya sudah menggunakan versi 2.0.0 beta karena saya tidak membangun situs web penting dan menurut saya webpack 1.13 tidak menyelesaikan bidang jsnext:main/module .

Saya bukan ahli bundler tapi saya pikir saya lebih suka menggunakan bidang "modul" dari package.json bukan? "main" tampaknya untuk kode yang sudah ditranskripsikan sejauh yang saya tahu. Tetapi karena konfigurasi webpack memungkinkan untuk memasukkan/mengecualikan transpilasi, saya tidak yakin itu relevan. Adakah rekomendasi di antara 3 bidang mana yang lebih suka saya gunakan?

@slorber Saya pikir webpack hanya mendukung main seperti NPM. Anda dapat menggunakan itu.
Kita dapat memeriksa filepath di fungsi exclude di next.conf.js

Hmm sesuai dengan apa yang saya lihat dalam latihan melawan Next 2.x Saya telah melihat modul berfungsi (tetapi gagal kemudian saat runtime karena tidak ditranskripsi ) sementara harus didukung .

Bagaimanapun, jsnext:main atau module tampaknya bukan solusi untuk masalah ini sehingga untuk modul internal perusahaan hanya mengaktifkan transpilasi mungkin sudah cukup

Masyarakat belum menyepakati satu pendekatan kan? Misalnya, saya dapat menggunakan react-youtube yang lain di luar kotak tanpa masalah. Saya berasumsi sejumlah besar modul transpile sebelum diterbitkan?

Ref: https://github.com/rauchg/blog/blob/master/components/post/youtube.js

Ya, masuk akal untuk selalu melakukan transpile sebelum mempublikasikan karena Anda tidak tahu siapa/bagaimana modul akan digunakan dan Anda tidak ingin memaksa klien untuk mengatur pengaturan babel yang sesuai untuk lib Anda. Itulah yang disarankan Rollup : untuk menerbitkan modul yang ditranspilasikan dengan cara yang berbeda sehingga bundler dapat memutuskan mana yang akan digunakan.

Tetapi untuk paket internal perusahaan, pengaturan transpilasi mungkin sama di beberapa proyek (seperti preset babel) dan masuk akal bagi saya untuk membiarkan bundel klien mengubah semua dependensi perusahaan

Sangat setuju @slorber - ini akan sangat berguna untuk modul internal jika Anda memecah proyek Anda dan mengisolasi hal-hal sebanyak mungkin.

Dan @rauchg / @arunoda yang mendukung RegExp akan sangat bagus, sehingga Anda dapat memiliki satu entri yang menangkap semua modul internal perusahaan, menggunakan ruang nama org NPM:

// next.config.js
module.exports = {
  transpileModules: [
    /^\@my-npm-org\/.*/
  ]
}

Saran yang bagus @philcockfield

Hei, mungkin ada baiknya menawarkan beberapa preset. Bagi saya sebagian besar alat (tautan Lerna/npm ...) bergantung pada symlink jadi mengapa tidak sesuatu yang sederhana seperti:

```javascript
modul.ekspor = {
transpileModules: ["symlink"]
}
````

Semakin saya menggunakan next.js dengan sungguh-sungguh, dan membangun perpustakaan modul yang kaya di sekitarnya, semakin penting fitur ini. Ini menjadi PITA nyata yang mereplikasi langkah kompilasi babel di modul internal saya.

🚀🤖

Saya sedang mengerjakan ini hari ini :)

@philcockfield coba ini: https://github.com/zeit/next.js/pull/749

terima kasih @arunoda

Jadi seperti yang dikomentari PR Anda jika ini tidak mendukung symlink, fiturnya akan sedikit terbatas karena tidak akan berfungsi dengan tautan npm atau Lerna, tetapi hanya untuk modul npm yang tidak ditranskripsi (kan? Saya tidak melihat yang lain usecase kecuali jika Anda melakukan modul di dalam /node_modules )

Mengapa tidak mendukung symlink? apakah lebih sulit untuk mendukung?

Saya juga ingin menguji cabang Anda di aplikasi saya, tetapi saya tidak yakin apa cara terbaik untuk melakukannya. Apakah ada prosedur yang diketahui sehingga kami dapat dengan mudah menguji cabang dan tidak terlalu menyakitkan bagi penguji? Saya sudah mencoba beberapa hal seperti:

  • npm install https://github.com/arunoda/next.js.git#add -706 : gagal karena folder /bin berikutnya kosong di repo github
  • git clone dari garpu di dalam /node_modules: tidak banyak berhasil (tapi mungkin karena pengaturan Lerna khusus saya)

Apa cara terbaik untuk menguji garpu saat ini?

Jika Anda ingin melakukan ini dengan next.config.js : module.exports = { webpack: (config , maka config.module.rules memiliki beberapa hal, sepertinya Anda perlu mengubah salah satu aturan ini, atau menambahkannya? :

  { 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: [] } } ]

Menantikan sintaks yang lebih sederhana yang disarankan.

Maaf atas ketidaktahuan saya, saya tidak bisa melihat apa resolusi masalah ini? Kami ingin mengimpor es6 ke basis kode kami, kami membutuhkan tree-shaking .

Apakah ada PR tentang ini?

@andrewmclagan Masalah ini masih terbuka dan memiliki PR terkait yang mungkin tidak akan memuaskan semua (seperti pengguna LernaJS)

Ini statusnya apa? Apakah ada cara lain untuk membuat webpack berikutnya untuk mentranspile file yang diimpor dari node_modules ?

@slorber saya akan melihat PR. Kontribusikan kasus penggunaan kami.

Saya menghadapi jenis masalah serupa. Mencoba menggunakan paket get-urls . Bekerja temukan dengan dev tetapi ketika saya mengkompilasinya. Saya mendapat kesalahan dari uglify

...
{ Error: commons.js from UglifyJs
...

Apakah ada solusi untuk ini tolong?

Arunoda akan mengerjakannya kapan-kapan di sini. Dia telah melakukannya sebelumnya di #749

Saya ingin melihat fitur ini diimplementasikan. Seperti yang disebutkan @philcockfield , ini adalah skenario umum untuk membangun perpustakaan modul yang bergantung pada transpilasi Next.js, dan akan sangat bagus untuk dapat berbagi komponen di antara proyek.

Ini tidak hanya diperlukan untuk menggoyang pohon. Juga untuk plugin babel seperti styled-jsx . Jadi, jika Anda memiliki modul (seperti perpustakaan) yang menggunakan plugin babel, solusi terbaik adalah dengan menyertakan kode sumber ES6 dan mengizinkan aplikasi Anda untuk mentranspilenya dari node_modules. Tentu saja selanjutnya sudah termasuk styled-jsx secara default.

Inilah yang saya lakukan

// 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);

Saya pada dasarnya mengganti setiap exclude dengan fungsi khusus.
Saya tidak tahu apa yang saya lakukan salah, tetapi saya tidak bisa membuatnya bekerja.
Saya ingin konten node_modules/mycomponents juga ditranspilasikan oleh Next.js

Itu bahkan tidak berfungsi jika saya sepenuhnya menimpa semua pengecualian dengan array kosong

exports.webpack = config => (config.module.rules = config.module.rules.map(({exclude, ...rest}) => ({
  exclude: [],
  ...rest
})), config);

Tolong bantu aku :)
Terima kasih

Hai teman-teman ( @thealjey ) Saya telah jsnext:main selama berbulan-bulan sekarang.

Saya tidak menggunakan next.js tapi saya harap ini membantu.

@damianobarbati tidak, sayangnya tidak
Mengonfigurasi webpack secara langsung untuk mengubah apa pun tidak sulit, tetapi saya berjuang untuk membuat ini berfungsi dalam konteks Next.js

halo semua, ada yang sudah menemukan solusi?

saya memiliki modul simpul tertaut ES6 lokal yang perlu saya impor dalam proyek saya tetapi saya tidak bisa mendapatkan voodoo webpack dengan benar!

Saya yakin ada cara yang lebih baik, tetapi kami menjalankan semuanya melalui babel saat dibangun:

next build && babel .next/*.js --out-dir . --presets=es2015,react

Apakah ini mati? Saya mencari cara untuk mengubah modul khusus dan sepertinya itu masih tidak mungkin.

@mattfelten ada di peta jalan untuk v5 👍

Adakah yang punya contoh solusi untuk ini?

@timneutkens Apakah ada timeline untuk ini? Hargai itu sering kali merupakan pertanyaan yang mustahil, tetapi kami mencoba menentukan tumpukan kami di tempat kerja mulai sekarang dan ini adalah penghalang yang cukup besar bagi kami! :)

Saran solusi juga valid.

@thealjey menyadari ini adalah komentar lama tetapi solusi Anda mungkin tidak berfungsi karena ada include ditentukan juga yang perlu diganti.

Pembaruan: melihat ke dalam strategi ini tetapi itu tidak waras mengingat semua pemuat yang berbeda untuk direktori modul yang berbeda dalam konfigurasi internal next.js. Ini harus kelas satu.

@chrisui solusi (sementara) saya adalah menggunakan babel-plugin-module-resolver , dikonfigurasi seperti ini - "plugins": [["module-resolver", {"root": ["./"]}]]
itu sama sekali bukan solusi yang sempurna, tetapi, karena semuanya gagal, itu berfungsi untuk saat ini
terima kasih untuk itu saya tidak perlu menulis banyak ../ dengan setiap impor
ini mungkin benar-benar solusi yang lebih baik untuk beberapa, meskipun tentu saja tidak membantu dengan dapat digunakan kembali

@thealjey bisakah Anda memberikan contoh?
Saya memiliki pengaturan proyek di mana saya mencoba ini tetapi tidak berhasil ...
https://github.com/jamesgorrie/nappy

Saya akan dengan senang hati mencoba mendapatkan PR karena ini akan membuat hidup kita jauh lebih mudah, tetapi ada beberapa pertanyaan seperti: Haruskah next.js mendukung transpiling modul tertentu atau haruskah ini tergantung pada transpiler, tetapi next.js mengikuti resolusi modul dengan lebih ketat. Tidak yakin harus bertanya kepada siapa atau harus mulai dari mana di sini karena baru mengenal next.js .

itu ada di peta jalan untuk v5 👍

@timneutkens apakah ini membuatnya menjadi v5?

ingin tahu.

Lihat saja di mana itu digabungkan. ini digabungkan 8 hari yang lalu. 5.0.0 dirilis 2 hari yang lalu. dari cabang kenari tempat ini digabungkan menjadi...

Adakah yang punya contoh bagaimana ini bisa diterapkan? Apakah seharusnya bekerja seperti ini, seperti yang disebutkan di atas?

module.exports = {
    transpileModules: ['my-npm-module']
}

atau terlihat berbeda?

Saya bingung. @timneutkens Tautan yang disebutkan di atas adalah untuk PR yang masih terbuka. Apakah ini BELUM digabung di v5?

EDIT: Sudahlah, ini hanya PR untuk menyoroti contoh.

Ini adalah contoh, Anda dapat menggunakan contoh tanpa digabung. transpileModules adalah sesuatu yang akan kita tangani nanti.

Sebagai aturan umum: Saat masalah terbuka, itu tidak dirilis.

@brianyingling Saya telah mengubah contoh menjadi plugin untuk solusi sementara (hanya v5).
Ini bekerja untuk kami saat ini, sampai solusi resmi yang lebih kuat diterapkan.

https://www.npmjs.com/package/@weco/next -plugin-transpile-modules

Saya ingin melihat contoh ini untuk satu modul di basis kode aplikasi.

Misalnya, saya memiliki modul yang saya gunakan di sisi server dan klien. Saya belum bisa mendapatkan salah satu contoh di atas untuk bekerja, baik dengan memfaktorkan modul ke dalam modul terpisah dan yarn link ing itu, atau dengan meretas aturan webpack.

Inilah repro sederhana: 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 memberi tahu saya ini karena saya menggunakan async/await dalam modul bersama. Saya kira solusi saya mungkin menghapus async/menunggu dan mengubah semuanya menjadi .then() -style callback.

Oke, saya menemukan perbaikan yang cocok untuk saya.

Pertama, saya menambahkan pengaturan config.resolve.symlinks = false ke konfigurasi next.config.js per https://github.com/zeit/next.js/issues/3018#issuecomment -380879576

// next.config.js
webpack: (config, { dev }) => {
  config.resolve.symlinks = false
  return config
}

Kemudian saya meletakkan perpustakaan bersama saya — file .js yang menggunakan ekspor CommonJS dan kata kunci async / await — di subdir aplikasi bernama 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": { ... }
}

Dan akhirnya saya menambahkan skrip postinstall untuk menautkan semuanya bersama-sama ketika ada yang melakukan yarn install di aplikasi utama:

// package.json
{
  ...
  "scripts": {
    "postinstall": "cd shared ; yarn -s unlink ; yarn link && yarn && cd .. && yarn link @myapp/shared",
   ...

Sekarang tes Mocha saya lulus di sisi server, server Koa kustom saya dimulai dengan baik, dan tidak ada lagi Cannot assign to read only property 'exports' of object '#<Object>' gila di halaman NextJS saya.

Saya memiliki masalah yang sama saat memutakhirkan ke NextJs 5.1.0. Satu atau dua modul simpul berikutnya tidak mentranspilasikan fungsi panah gemuk dan melempar kesalahan di IE11. Saya sebelumnya telah menyiapkan polyfill individual dan pada akhirnya saya memilih untuk menargetkan file modul tersebut dengan babel-polyfill di next.config.js dengan ini:

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 })
  }
}

Semoga ini bisa membantu seseorang.

ESM bekerja seperti pesona.

Dengan server Next.js khusus di index.js , saya dapat menjalankan perintah ini untuk memulai server dan esm berjalan dengan sempurna, menyelesaikan modul ES dalam paket proyek yang terhubung dengan Lerna.

node -r esm index.js

@curran keren, bisa ganti babel-node ?

@curran Saya akan menghindari melakukan itu dalam produksi

@blackbing saya tidak tahu.

@thealjey Kenapa begitu?

Jika ada yang mencari solusi cepat dan mudah, inilah yang saya lakukan. Saya membuat subdirektori, shared/ , dengan kode apa pun yang ingin kami jalankan di backend melalui skrip Node mandiri dan klien melalui NextJS. Ia memiliki package.json dan mendeklarasikan namanya sebagai @myproject/shared .

Kemudian, di proyek utama (induk), saya menambahkan skrip postinstall ke package.json seperti ini: cd shared && yarn -s unlink >/dev/null 2>&1 ; yarn -s link && yarn -s && yarn link @myproject/shared — lalu jalankan yarn setidaknya sekali, dan ubah impor Anda menjadi import { whatever } from '@myproject/shared/somefile'

Dengan cara ini kode bersama bekerja tanpa langkah transpilasi gila, ditambah Anda tidak perlu menjalankan ulang yarn / npm setiap kali Anda membuat pembaruan karena yarn link membuat tautan simbolik.

Bagi mereka yang menggunakan TypeScript, @weco/next-plugin-transpile-modules seharusnya tidak berfungsi. Saya membuat garpu untuk menangani withTypescript Berikutnya: https://github.com/KeitIG/next-plugin-transpile-modules

Saya masih perlu mencari cara untuk melakukan sesuatu dengan benar ketika kita perlu memiliki kode sisi server di TypeScript juga.

Ada berita tentang ini?

Dan satu lagi oleh saya, di inti berikut. Ini menangani TypeScript, dan juga paket spesifik dari @scope , daripada semua paket. https://Gist.github.com/trusktr/44400d0d016c506629b4f914799dc9cd

Saya baru saja mengumpulkan contoh kerja sederhana yang menggunakan esm dan lerna

https://github.com/curran/nextjs-esm-example

/cc @jdalton

Secara pribadi, ini berfungsi dengan next.config.js :

module.exports = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.js$/,
      include: /node_modules/,
      use: [
        options.defaultLoaders.babel
      ]
    })

    return config
  }
}

Itu babel semuanya di node_modules , yang saya butuhkan untuk mencapai kompatibilitas IE 11 ...

Saya juga menghargai solusi untuk ini, berjuang dengan menambahkan paket npm yang tidak diterjemahkan ke proyek saya. Harus mengunduhnya ke vendor/untuk saat ini :(
Benar-benar menjengkelkan

@bel0v Saya yakin Anda seharusnya sudah dapat mencapai ini dengan next-plugin-transpile-modules . Masalah ini kemungkinan besar harus ditutup. cc/ @timneutkens

Saya masih ingin menyelidiki solusi alternatif.

Baru-baru ini Jamie menulis utas yang sangat rinci tentang masalah kompilasi node_modules: https://twitter.com/jamiebuilds/status/108084092525350912

Saya membaca utas oleh Jamie, meskipun saya juga ingin berbagi pendapat Henry Zhu dan Babel tentang situasi dan solusi ini.
https://babeljs.io/blog/2018/06/26/on-consuming-and-publishing-es2015+-packages

(Tidak setuju dengan Tim, hanya berpikir saya akan berbagi, banyak pro dan kontra. Mungkin membantu Tim dalam menyelidiki solusi alternatif)

Ya, kami telah berbicara dengan banyak orang tentang masalah ini selama setengah tahun terakhir, termasuk Henry

Kekhawatiran tentang transpiling node_modules meskipun, ingin mengubah paket Anda sendiri dalam monorepo adalah persyaratan yang sangat umum, yang kekhawatiran ini tidak berlaku

@dcalhoun Saya sudah mencobanya tetapi sayangnya saya masih mendapatkan kesalahan token yang tidak terduga. Ada masalah 7 Berikutnya terbuka pada plugin ini yang mungkin terkait

@bel0v

Anda harus membaca FAQ ;) ada solusi untuk masalah ini: https://github.com/martpie/next-plugin-transpile-modules#i -have-trouble-making-it-work-with-nextjs-7

Saya telah menggunakan plugin ini di banyak proyek, dan itu menyelesaikan pekerjaan dengan baik. Masalah 7 Berikutnya aneh, saya tidak yakin apakah ini berasal dari Berikutnya atau Babel, saya tetap membuka masalah di sini: https://github.com/zeit/next.js/issues/5393

@martpie ya saya yakin saya sudah mencobanya .. bagaimanapun saya akan mencobanya lagi

@martpie kami sudah mulai menggunakan next7 dengan babel.config.js yang konsisten, dan ruang kerja benang, saya mungkin melihat apakah saya dapat menyiapkan contoh sederhana.

Saya telah bercabang contoh dasar di sini
https://github.com/bel0v/learnnextjs-demo
di dalamnya, saya menginstal dependensi yang tidak ditranspilasikan (elemen berkabel), mendapat kesalahan build Unhandled Rejection (SyntaxError): Unexpected token { dan mencoba memperbaikinya dengan cara yang disarankan.
Saya pikir mungkin saya perlu beberapa plugin babel tambahan agar bisa berfungsi..

@bel0v di FAQ lagi, ada penjelasan mengapa setup Lerna tidak bekerja (TL,DR; Anda mungkin menggunakan salah)

@martpie ah, mengerti! Tidak menyadari bahwa paket pihak ketiga diatur dengan Lerna. Terima kasih

Sepertinya https://twitter.com/jamiebuilds telah ditangguhkan, jadi tidak dapat membaca utas di sana lagi. #3018 Sudah ditutup sehubungan dengan masalah ini, jadi saya ingin tahu apa pendekatan alternatif yang dipertimbangkan?
Apakah ini mewakili keadaan seni/praktik terbaik next.js untuk atm kasus penggunaan ini?
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

Jadi, jika Anda, seperti saya, sedang mengerjakan proyek yang harus mendukung IE11, Anda benar-benar harus mengubah semua kode di dalam node_modules/ . Di Next.js 7.x saya menggunakan pengaturan berikut, yang bekerja dengan baik.

Sayangnya, itu berhenti bekerja di Next.js 8.x dengan kesalahan bahwa modul gagal mengimpor modul lain karena tidak memiliki ekspor default. Saya kemudian datang dengan konfigurasi di bawah ini untuk Next.js 8.x, yang hanya mengubah kode dalam node_modules/ dengan @babel/preset-env , dan tidak ada plugin lain.

Ini digabungkan dengan menyetel properti browserlist di package.json :

  "browserslist": "defaults, IE >= 11, EDGE >= 14, Safari >= 11, Chrome >= 41, Firefox >= 52",

7.x selanjutnya

next.config.js

module.exports = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.js$/,
      include: /node_modules/,
      use: [
        options.defaultLoaders.babel,
      ],
    })

    return config
  },
}

Selanjutnya.js 8.x

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
  },
}

Sayangnya, saya belum menemukan cara menggunakan @babel/plugin-transform-runtime dengan pengaturan ini, jadi mungkin akan mengeluarkan beberapa pembantu dalam kode semoga gzip menanganinya 😅


Saya pikir akan luar biasa jika Next.js dapat memberi kami opsi untuk mengubah node_modules/ untuk bekerja dengan browserlist Anda miliki. Sepertinya setiap situs besar yang memiliki jenis pengguna korporat bergantung pada ini untuk mendukung browser lama dengan benar.

Sebagai pengelola next-transpile-modules (berdasarkan karya luar biasa @jamesgorrie), saya senang membantu siapa pun yang menghadapi masalah ini di sini.

Saya telah mengerjakan proyek profesional selama lebih dari setahun dengan plugin ini, dan sejauh ini berfungsi dengan baik.

Dukungan asli dari Next.js tentu saja akan luar biasa dan saya akan dengan senang hati membantu mengintegrasikan fitur ini ke dalam paket next . Saya tahu Tim memiliki beberapa ide yang ingin dia coba, tetapi bagaimanapun juga.

Bersulang!

@martpie Saya dengan cepat melihat proyek Anda, tetapi tidak menemukan cara cepat untuk mengubah modul _all_, apakah itu mungkin? ️

Juga, saya melihat bahwa Anda memilih options.defaultLoaders.babel dan menggunakannya sebagai babel loader. Ketika melakukan itu dengan Next.js 8.x saya memiliki masalah bahwa beberapa modul akan gagal dikenali dengan benar sebagai modul CJS setelah itu, dan kemudian lib lain akan gagal untuk mengimpornya, misalnya:

./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'.

Itu sebabnya saya beralih untuk menyediakan konfigurasi babel khusus untuk node_modules/ , yang hanya mengubah kode menggunakan preset-env , dan melewatkan transformasi khusus Next.js. Apa pendapat Anda tentang pendekatan ini?

Salam

@LinusU Mungkin coba transpileModules: ['(.*?)'] dan beri tahu saya jika berhasil?

Tapi itu mungkin tidak berfungsi di rilis besar mendatang, jadi berhati-hatilah.

Secara lebih umum, saya tidak merekomendasikan (baca "sangat tidak disarankan") untuk mengubah seluruh folder node_modules , itu akan memakan waktu lama untuk dikompilasi dan paket harus menyediakan kode yang kompatibel dengan ES3 (jadi kompatibel dengan IE11).

Hanya transpile modul yang Anda butuhkan! (seperti lodash-es , modul lokal dll...)

paket harus menyediakan kode yang kompatibel dengan ES3 (jadi kompatibel dengan IE11).

Ini bukan kenyataan yang saya lihat, dan saya sebenarnya tidak setuju. Penulis modul tidak akan pernah tahu persis browser mana yang saya targetkan, dan jika mereka mengirimkan kode lama, mereka berpotensi menghukum pengguna yang menargetkan browser modern.

itu akan memakan waktu lama untuk dikompilasi

Agak lambat saat startup untuk saya, tetapi setelah itu, tampaknya di-cache dan ketika membuat perubahan pada halaman tertentu saya melihat pemuatan ulang yang hampir instan.

Hanya transpile modul yang Anda butuhkan!

Ini mengharuskan saya untuk mengetahui dengan tepat paket mana yang kompatibel dengan IE11 dan mana yang tidak, serta menjaga agar informasi ini tetap mutakhir kapan pun ada dependensi (bahkan dependensi sementara) berubah. Saya tidak melihat bagaimana ini realistis

Yang penting adalah titik masuk ESM yang disediakan di package.json module umumnya ES5 dengan ES6 impor/ekspor untuk tree shake. Jadi ini adalah pekerjaan untuk bundler (Webpack) dan bukan transpiler (Babel), kecuali dinyatakan lain. Banyak paket terpelihara dengan baik sudah memiliki titik masuk ESM, misalnya redux/es untuk Redux yang disebutkan oleh OP.

Jika Anda ingin melakukan ini dengan next.config.js : module.exports = { webpack: (config , maka config.module.rules memiliki beberapa hal, sepertinya Anda perlu mengubah salah satu aturan ini, atau menambahkannya? :

  { 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: [] } } ]

Menantikan sintaks yang lebih sederhana yang disarankan.

Bekerja dengan baik untuk saya

{
    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']
    }
},

Saya mengalami masalah ini menggunakan repo mono Lerna dan bertanya-tanya apa penyebabnya. Karena kesalahan berasal dari webpack, itu tidak memberikan detail yang bagus selain itu tidak ada pemuat, yang tidak membantu. Untungnya saya menemukan masalah github ini!

Saya akan meninggalkan solusi saya di sini untuk orang lain yang mencari masalah ini dan juga menggunakan Lerna:

Buat skrip prapublikasi untuk paket bersama yang mengubah sumber ke direktori dist dan beri tahu Lerna untuk menunjuk ke direktori dist saat menautkan:

// 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"
}

Sekarang ketika Anda lerna bootstrap itu akan menjalankan skrip pra-penerbitan dan mengubah sumbernya sehingga Berikutnya dapat menggunakannya.

Jika Anda menggunakan lerna Anda dapat membuat symlink untuk ditranspilasikan menggunakan next-transpile-modules . Cara menggunakan paket tersebut dengan lerna tertulis di bagian bawah dokumentasi.

Bagi siapa pun yang mencari kode berbagi di seluruh aplikasi NextJs, saya hanya ingin melaporkan bahwa solusi @LinusU bekerja untuk saya ketika mencoba membagikan komponen dan utilitas React antara beberapa aplikasi NextJs di mono repo saya:

// 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
        })
        }
    }
}

Saya menggunakan NextJs versi terbaru pada saat posting ini.

@Lwdthe1 Saya mencoba kode Anda dan awalnya mendapatkan kesalahan ini:

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

Melakukan beberapa penyesuaian dan berakhir dengan ini:

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
  }
};

Tetapi mengalami kesalahan lain:

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)
....

yang tampaknya telah dihadapi sebelumnya di #2850 dan #883.

Jadi sepertinya satu-satunya solusi adalah: https://github.com/martpie/next-transpile-modules#but -i-really-need-to-make-it-work-with-lerna

Dari apa yang saya dengar akan segera disajikan RFC bagaimana Next.js berencana untuk menyelesaikan masalah ini, tetapi jika seseorang perlu memperbaikinya sekarang, saya telah menerbitkan di npm solusi saya dari https://github.com/ zeit/next.js/pull/10098 yang dapat Anda gunakan dengan memasukkan yang berikut di package.json:

    "next": "npm:@sheerun/[email protected]",

dan mengikuti next.config.js:

  babelIncludeRegexes: [/turf/],

(dalam kasus saya, saya membutuhkan semua file rumput untuk dikompilasi dengan babel)

Masalah ini memiliki kemajuan?

Saya menggunakan next.js 9.2.0, tetapi opsi babelIncludeRegexes tidak berfungsi

Masalah ini memiliki kemajuan?

next-transpile-modules bertujuan untuk memecahkan masalah ini dengan tepat, apakah Anda mencobanya?

Hai @martpie ,

Sudah memecahkan masalah saya .babelrc file edit. Saya merujuk masalah ini

Terima kasih

@martpie Saya menggunakan next-transpile-modules tapi tetap saja, saya menghadapi kesalahan di bawah ini ketika saya mencoba membangun aplikasi. Saya menggunakan monorepo dengan basis kode bersama. Mencoba mengakses komponen dari yang dibagikan seperti '@myapp/shared/components/componentname.js'. Saya menggunakan nextjs 9.x dan custom next.config.js .

Kesalahan
`
Penguraian modul gagal: Token tak terduga (12:4)
Anda mungkin memerlukan pemuat yang sesuai untuk menangani jenis file ini, saat ini tidak ada pemuat yang dikonfigurasi untuk memproses file ini. Lihat https://webpack.js.org/concepts#loaders
| const Pemintal = alat peraga => {
| const renderDefaultSpinner = (Kelas pemintal, { ...lainnya }) => (
>


| );
|

Terjadi kesalahan pembuatan
Kesalahan: > Pembuatan gagal karena kesalahan webpack
`

next.config.js
const withTM = require('next-transpile-modules')(['<strong i="26">@myapp</strong>']); module.exports = withPlugins([withTM, withBundleAnalyzer], { ... }

Tolong bantu apa yang saya lakukan salah di sini.

@ raghav1086 Bisakah Anda membuka masalah di repo? ;) itu akan menghindari kebisingan bagi orang-orang di luar sini.

+1

Saya memiliki direktori src/ untuk proyek saya dan lib/ untuk kerangka kerja pemula yang mengekspor beberapa utilitas/pembungkus umum yang saya gunakan kembali di beberapa aplikasi nextjs yang berbeda (titik awal saya)

lib tidak diperhatikan ketika saya memulai server dev. komponen apa pun dari lib/ jangan melalui pemuat dan berikan kesalahan

Saya menggunakan variasi solusi @Lwdthe1 ( https://github.com/zeit/next.js/issues/706#issuecomment-569041997 ) untuk memperbaiki masalah src dan lib dalam komentar saya di atas. Pada dasarnya hal yang sama kecuali ini menggunakan config.resolve.modules alih-alih mengulang melalui array 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],
    });

Apa solusi yang berfungsi untuk lerna, nextjs, dan babel hari ini?

Saya mencoba untuk menghindari pra-transpili perpustakaan saya sebelum mengimpor, dan saya telah menabrak dinding bata dengan setiap solusi di sini. Inilah yang saya tidak bisa bekerja:

  • next-transpile-modules .
  • mengatur ulang pengaturan preset-env.
  • memperbarui aturan next-babel-loader include dan exclude masing-masing untuk lulus/gagal.

@mikestopcontinues next-transpile-modules bekerja di luar kotak untuk saya dengan TypeScript.

@calebmpeterson dan @martpie (saya melihat Anda! ). Saya memutar kembali ke steker, dan masalahnya sepertinya tidak ada cara untuk merujuk sub-modul. Misalnya, pola '@mono/komponen' tidak akan mendukung pengimporan '@mono/komponen/Div' atau apa pun. Dan menentukan '@mono/components/Div' sebagai pola juga tidak berfungsi ... bukan berarti saya ingin melakukan itu untuk setiap komponen yang dibagikan. Saya juga mencoba merekayasa balik generasi regex untuk membuat pola kecocokan, dan sementara output regex berfungsi, ada hal lain yang terjadi di bawah tenda yang tidak.

Idealnya, saya hanya ingin menentukan '@mono` untuk mengurus semuanya, dan membiarkan package.json saya menjadi satu-satunya sumber kebenaran untuk apa yang bergantung pada masing-masing aplikasi saya. Demikian pula, saya ingin menghindari pemeliharaan file indeks yang mengimpor/mengekspor segala sesuatu di setiap lib saya hanya untuk dapat mengakses sub-modul.

Untuk memutar kembali, saya percaya masalah saat ini dapat diselesaikan sepenuhnya jika ada beberapa cara untuk melewati rootMode: 'upward' melalui next-babel-loader , sehingga babel dapat menangani logika transpiling. Mungkin ini membuka masalah terkait Next lainnya, tetapi akar masalahnya tampaknya adalah cara atipikal Next terjerat ke webpack dan babel. Tentunya, ada cara untuk memisahkan babel-loader dari logika tambahan Berikutnya?

Hanya pembaruan di bagian depan next-transpile-modules . Saya telah salah mendiagnosis kesalahan. Tidak ada impor yang berfungsi menggunakan metode ini (indeks atau submodule) jika Anda memerlukan konfigurasi .babelrc kustom. Pengaturan khusus tidak diterapkan pada kode yang diperlukan. Ini lagi-lagi masalah rootMode: 'upward' .

@mikestopcontinues Anda perlu menggunakan babel.config.js (konfigurasi global) dengan next-transpile-modules , dan bukan .babelrc (konfigurasi lokal), dijelaskan di FAQ ;)

@martpie Anda tidak tahu betapa malunya saya. Saya harus membaca baris itu belasan kali dalam beberapa minggu terakhir dan tidak pernah repot-repot untuk mengklik masalah tersebut. Itu benar-benar berhasil. Terima kasih!

modul-transpile-berikutnya memecahkan Bereaksi untuk saya. Sekarang melempar bahwa saya menggunakan kait yang tidak valid, sementara saya mengubah TIGA modul contoh

Bisakah seseorang mengulangi konfigurasi apa yang terbaik untuk membuat transpilasi berfungsi. Saya tidak mengerti apa yang harus saya tulis di babel.config.js

@masbaehr dalam banyak kasus hanya menambahkan next-transpile-modules ke pengaturan next.config Anda

Satu-satunya masalah adalah next-transpile-modules tidak mendukung Yarn 2 pnp.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat