使用纱线工作区将 ui 库与汇总捆绑时导入未定义
Posted
技术标签:
【中文标题】使用纱线工作区将 ui 库与汇总捆绑时导入未定义【英文标题】:import undefined when bundling ui library with rollup using yarn workspaces 【发布时间】:2018-12-03 16:17:52 【问题描述】:对于一个新项目,我开始使用汇总来捆绑 UI 库并在反应应用程序中使用该库。我还在使用 yarn 工作区来管理 UI 库和 Web 应用程序之间的内部依赖关系。
当我尝试在我的网络应用程序中使用 UI 库时,导入返回未定义并引发“无法从未定义中获取”错误。
TypeError:无法读取未定义的属性“NavBar” [0] 在 App (C:/Users/user/dev/project/packages/project-web/src/pages/App.jsx:9:6)
webapp 代码:
import React from 'react';
import NavBar from 'project-ui';
const App = () => (
<div>
<NavBar/>
<div>App component!x</div>
</div>
);
根包.json:
"name": "project",
"version": "1.0.0",
"private": true,
"workspaces": [
"packages/*"
]
UI 包.json:
"name": "project-ui",
"version": "1.0.0",
"main": "dist/project-ui.cjs.js",
"jsnext:main": "dist/project-ui.es.js",
"module": "dist/project-ui.es.js",
"files": ["dist"],
"scripts":
"build": "rollup -c"
,
"peerDependencies":
"react": "16.3.2",
"react-dom": "16.3.2"
,
"devDependencies":
"babel-core": "6.26.3",
"babel-plugin-external-helpers": "6.22.0",
"babel-preset-env": "1.6.1",
"babel-preset-react": "6.24.1",
"babel-preset-stage-2": "6.24.1",
"rollup": "0.60.0",
"rollup-plugin-babel": "3.0.4",
"rollup-plugin-commonjs": "9.1.3",
"rollup-plugin-node-resolve": "3.0.0",
"rollup-plugin-replace": "2.0.0",
"rollup-plugin-uglify": "4.0.0"
网络应用程序包.json:
"name": "project-web",
"version": "1.0.0",
"scripts":
"build": "webpack --colors --display-error-details --config=webpack/webpack.dev.js",
"dev": "concurrently --kill-others \"npm run dev:start\"",
"dev:start": "node ./server/index.js"
,
"dependencies":
"babel-polyfill": "^6.26.0",
"express": "^4.16.3",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"project-ui": "1.0.0"
,
"devDependencies":
"babel-core": "^6.26.3",
"babel-eslint": "^8.2.3",
"babel-loader": "^7.1.4",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"concurrently": "^3.5.1",
"eslint": "^4.19.1",
"eslint-loader": "^2.0.0",
"eslint-plugin-react": "^7.7.0",
"piping": "^1.0.0-rc.4",
"webpack": "^4.6.0",
"webpack-cli": "^2.0.15",
"webpack-dev-middleware": "^3.1.3",
"webpack-dev-server": "^3.1.3",
"webpack-hot-middleware": "^2.22.1",
"webpack-node-externals": "^1.7.2"
汇总配置:
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import babel from 'rollup-plugin-babel';
import replace from 'rollup-plugin-replace';
import uglify from 'rollup-plugin-uglify';
import pkg from './package.json'
const FORMATS =
UMD: 'umd',
ES: 'es',
CJS: 'cjs'
;
const allowedFormats = [FORMATS.UMD, FORMATS.ES, FORMATS.CJS];
const bundle = (fileFormat, format, minify) =>
if (!allowedFormats.includes(format))
throw new Error(`Invalid format given: $format`);
const shouldMinify = minify && format === FORMATS.UMD;
const externals = format === FORMATS.UMD
? Object.keys(pkg.peerDependencies || )
: [
...Object.keys(pkg.dependencies || ),
...Object.keys(pkg.peerDependencies || )
];
return
input: 'src/index.js',
output:
file: fileFormat.replace('format', shouldMinify ? `$format.min` : format),
format,
name: 'project-ui',
exports: 'named',
globals:
react: 'React',
'prop-types': 'PropTypes'
,
external: externals,
plugins: [
resolve( jsnext: true, main: true ),
commonjs( include: 'node_modules/**' ),
babel(
exclude: 'node_modules/**',
),
format === FORMATS.UMD
? replace('process.env.NODE_ENV': JSON.stringify(shouldMinify ? 'production' : 'development'))
: null,
shouldMinify ? uglify() : null
].filter(Boolean)
;
;
export default [
bundle('dist/project-ui.format.js', format: FORMATS.UMD, minify: true),
bundle('dist/project-ui.format.js', format: FORMATS.CJS),
bundle('dist/project-ui.format.js', format: FORMATS.ES)
];
从汇总中实际生成的代码:
import React from 'react';
var NavBar = function NavBar()
return React.createElement(
'header',
null,
'nav bar'
);
;
module.exports = exports['default'];
export NavBar ;
原来的导航栏:
import React from 'react';
const NavBar = () => (
<header>
nav bar
</header>
);
export default NavBar;
index.js:
export default as NavBar from './NavBar/NavBar';
.babelrc:
"presets": [
["env",
"loose": true,
"modules": false,
"targets":
"browsers": ["last 2 versions"]
],
"react",
"stage-2"
],
"plugins": [
"transform-runtime",
"add-module-exports",
"external-helpers"
]
生成的汇总代码看起来没问题,所以我认为这是一个纱线问题,但我不确定。任何帮助将不胜感激!
问候 康奈尔
【问题讨论】:
exports['default']
返回什么? ;)
能否贴出 NavBar 的原始代码(不是 RollUp 生成的代码)
另外,你能发布你的 babel 配置吗?在生成它之后,我无法以任何方式获得与您相同的代码,这可能是问题
我添加了原始代码和 babel 配置。感谢您的回复!
@GuyT 当我在生成的代码末尾添加日志时,exports['default'] 的值是 NavBar: [Function: NavBar]
【参考方案1】:
问题一定出在您使用 babel/rollup 转译代码的方式上。我有一个活生生的例子,说明您的代码在online babel 中的外观:
为我生成的代码是:
import React from 'react';
const NavBar = () => React.createElement(
'header',
null,
'nav bar'
);
export default NavBar; // first define default and then we assign export['default']
module.exports = exports['default'];
请注意,在此代码中,我们首先将 export default 分配给所需的值,然后我们分配 export['defaults'] (当我调试您的示例时,我发现 export['default']
是 undefined
,因此您会收到错误 @ 987654325@,因为您将 undefined 传递给导出。
这是由插件'add-module-exports'完成的,如果你真的需要module.exports,这是必要的(除非存在NodeJS或一些RequireJS,否则不应该需要它)。
为了使它工作,只需从你的插件中删除"add-module-exports"
项目-ui .babelrc
。
【讨论】:
感谢您的帮助!以上是关于使用纱线工作区将 ui 库与汇总捆绑时导入未定义的主要内容,如果未能解决你的问题,请参考以下文章
从库导入的 React 组件的 Material-Ui 主题化问题
Rails 6 无法导入纱线依赖项:未捕获错误:模块解析失败:意外字符“#”(1:0)