告诉 webpack 一个第三方模块使用 ES 模块
Telling webpack a 3rd party module uses ES Modules
在尝试解释之前,我将直接跳入其中:
- 创建一个 next.js 脚手架。
npx create-next-app
- (可选)我在这里添加了打字稿。将任何 .js 重命名为 .ts,然后 运行
yarn dev
- 安装第 3 方库,在我的例子中是 openlayers。
yarn add ol
- 将其中一个 openlayers 示例改编到应用程序中。例如,这是我的
pages/index.tsx
:
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”等键。
在尝试解释之前,我将直接跳入其中:
- 创建一个 next.js 脚手架。
npx create-next-app
- (可选)我在这里添加了打字稿。将任何 .js 重命名为 .ts,然后 运行
yarn dev
- 安装第 3 方库,在我的例子中是 openlayers。
yarn add ol
- 将其中一个 openlayers 示例改编到应用程序中。例如,这是我的
pages/index.tsx
:
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”等键。