TypeScript+Rollup构建Lit2项目无法导入默认导出,求解决
问题
基于Lit2创建自定义Web组件项目,使用open-wc官方生成器搭建。当前遇到外部库导入问题:无法导入带有default export的库(如axios、JsBarcode、device-detector-js等),浏览器控制台提示:
Uncaught SyntaxError: The requested module '[...]/node_modules/device-detector-js/dist/index.js' does not provide an export named 'default'
但导入named export一切正常。项目配置如下:
tsconfig.json
{ "compilerOptions": { "target": "es6", "module": "esnext", "moduleResolution": "node", "noEmitOnError": true, "lib": ["es2016", "esnext", "dom"], "strict": true, "esModuleInterop": true, "allowJs": true, "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "importHelpers": true, "outDir": "build", "sourceMap": true, "inlineSources": true, "rootDir": "./", "incremental": true, "resolveJsonModule": true, "isolatedModules": false, "noLib": false, "suppressImplicitAnyIndexErrors": true, "noImplicitAny": true }, "include": [ "**/*.ts" ], "exclude": [ "node_modules" ] }
rollup.config.js
import nodeResolve from '@rollup/plugin-node-resolve'; import babel from '@rollup/plugin-babel'; import html from '@web/rollup-plugin-html'; import { importMetaAssets } from '@web/rollup-plugin-import-meta-assets'; import { terser } from 'rollup-plugin-terser'; export default { input: 'index.html', output: { entryFileNames: 'bundle.js', chunkFileNames: '[name].js', assetFileNames: '[name][extname]', format: 'es', dir: 'dist' }, preserveEntrySignatures: false, plugins: [ /** Enable using HTML as rollup entrypoint */ html({ minify: true, injectServiceWorker: false }), /** Resolve bare module imports */ nodeResolve(), /** Minify JS */ terser(), /** Bundle assets references via import.meta.url */ importMetaAssets(), /** Compile JS to a lower language target */ babel({ babelHelpers: 'bundled', presets: [ [ require.resolve('@babel/preset-env'), { targets: [ 'last 3 Chrome major versions', 'last 3 Firefox major versions', 'last 3 Edge major versions', 'last 3 Safari major versions' ], modules: false, bugfixes: true } ] ], plugins: [ [ require.resolve('babel-plugin-template-html-minifier'), { modules: { lit: ['html', { name: 'css', encapsulation: 'style' }] }, failOnError: false, strictCSS: true, htmlMinifier: { collapseWhitespace: true, conservativeCollapse: true, removeComments: true, caseSensitive: true, minifyCSS: true } } ] ] }) ] };
index.html脚本标签
<script type='module' src='./build/src/index.js'></script>
此前一直使用Webpack,首次使用Rollup,怀疑是Rollup配置导致该问题,寻求解决办法。
解决办法
这个问题的核心是Rollup默认仅处理ES模块,而你用到的部分库(如axios、device-detector-js)可能以CommonJS格式发布,或其ES模块输出未正确处理default导出。Rollup需要额外插件转换CommonJS模块的导出逻辑,使其适配ES模块规范。
步骤1:安装@rollup/plugin-commonjs
执行安装命令:
npm install --save-dev @rollup/plugin-commonjs
步骤2:修改rollup.config.js配置
在配置文件中导入并添加该插件,注意需放在nodeResolve插件之后:
import nodeResolve from '@rollup/plugin-node-resolve'; import babel from '@rollup/plugin-babel'; import html from '@web/rollup-plugin-html'; import { importMetaAssets } from '@web/rollup-plugin-import-meta-assets'; import { terser } from 'rollup-plugin-terser'; // 新增导入commonjs插件 import commonjs from '@rollup/plugin-commonjs'; export default { input: 'index.html', output: { entryFileNames: 'bundle.js', chunkFileNames: '[name].js', assetFileNames: '[name][extname]', format: 'es', dir: 'dist' }, preserveEntrySignatures: false, plugins: [ html({ minify: true, injectServiceWorker: false }), nodeResolve(), // 新增commonjs插件,放在nodeResolve之后 commonjs({ include: 'node_modules/**' }), terser(), importMetaAssets(), babel({ babelHelpers: 'bundled', presets: [ [ require.resolve('@babel/preset-env'), { targets: [ 'last 3 Chrome major versions', 'last 3 Firefox major versions', 'last 3 Edge major versions', 'last 3 Safari major versions' ], modules: false, bugfixes: true } ] ], plugins: [ [ require.resolve('babel-plugin-template-html-minifier'), { modules: { lit: ['html', { name: 'css', encapsulation: 'style' }] }, failOnError: false, strictCSS: true, htmlMinifier: { collapseWhitespace: true, conservativeCollapse: true, removeComments: true, caseSensitive: true, minifyCSS: true } } ] ] }) ] };
步骤3:验证导入语法
确保default导入语法正确:
import axios from 'axios'; import DeviceDetector from 'device-detector-js';
若仍有问题,可尝试兼容式命名导入:
import * as axios from 'axios'; import * as DeviceDetector from 'device-detector-js'; // 使用时调用default属性 axios.default.get('/api');
补充说明
Webpack默认会自动处理CommonJS与ES模块的转换,而Rollup需要显式添加@rollup/plugin-commonjs完成该工作,这也是你之前用Webpack无问题、换Rollup后报错的原因。
内容的提问来源于stack exchange,提问作者Ovidiu
相关产品推荐
相关产品推荐

