告诉 webpack 一个第三方模块使用 ES 模块

Telling webpack a 3rd party module uses ES Modules

在尝试解释之前,我将直接跳入其中:

import React from 'react'
import Map from 'ol/Map'
import View from 'ol/View'
import TileLayer from 'ol/layer/Tile'
import { fromLonLat } from 'ol/proj'
import { OSM, TileDebug } from 'ol/source'

export default function() {
  const ref = React.useRef<any>()
  React.useEffect(() => {
    var osmSource = new OSM()
    new Map({
      layers: [
        new TileLayer({
          source: osmSource,
        }),
        new TileLayer({
          source: new TileDebug({
            projection: 'EPSG:3857',
            tileGrid: osmSource.getTileGrid(),
          }),
        }),
      ],
      target: ref.current,
      view: new View({
        center: fromLonLat([-0.1275, 51.507222]),
        zoom: 10,
      }),
    })
  }, [])
  return (
    <>
      <h1>hello world</h1>
      <div ref={ref} />
    </>
  )
}

现在我们导航到 http://localhost:3000 并收到以下错误:

/home/willian/Documentos/consumer/node_modules/ol/Map.js:4
import PluggableMap from './PluggableMap.js';
       ^^^^^^^^^^^^

SyntaxError: Unexpected identifier
    at Module._compile (internal/modules/cjs/loader.js:723:23)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)

好吧,这似乎是 openlayers 导出 es 模块,但 webpack 正试图将它们作为 commonjs 使用(来自 cjs/loader 路径)。有什么方法可以让 webpack 将模块解析为 es-modules 吗?

(附录)在 next.js 上,您可以通过 next.config.js 文件 docs 修改 webpack 配置。但是我到底应该在 webpack 配置上更改什么? Console.logging 进入规则部分当前输出:

[ { test: /\.(tsx|ts|js|mjs|jsx)$/,
    include:
     [ '/home/willian/Documentos/consumer',
       /next-server[\\/]dist[\\/]lib/,
       /next[\\/]dist[\\/]client/,
       /next[\\/]dist[\\/]pages/,
       /[\\/](strip-ansi|ansi-regex)[\\/]/ ],
    exclude: [Function: exclude],
    use: { loader: 'next-babel-loader', options: [Object] } } ]

尝试将 /[\\/]node_modules[\\/]ol/ 添加到 include 属性?


include:
 [ '/home/willian/Documentos/consumer',
   /next-server[\\/]dist[\\/]lib/,
   /next[\\/]dist[\\/]client/,
   /next[\\/]dist[\\/]pages/,
   /[\\/](strip-ansi|ansi-regex)[\\/]/,
   /[\\/]node_modules[\\/]ol/]

own-answer after some months

你不应该告诉 webpack 一个模块是 es-modules。

一个模块通过在 package.json 上声明一个额外的 module 键来告诉消费者它使用 es-modules。它的用途与 main 键类似,但 main 通常被理解为 commonjs 构建入口点。

package.json 上可能还有 webpack 习惯理解的其他“神奇”入口点标志,例如,angular 构建生成诸如“fesm2015”等键。