javascript – 使用纱线工作区将ui库与汇总捆绑在一起时导入undefined

对于一个新项目,我开始使用汇总来捆绑UI库并在反应应用程序中使用该库.我还使用纱线工作区来进行UI库和Web应用程序之间的内部依赖关系管理.

当我尝试在我的Web应用程序中使用UI库时,导入返回undefined并抛出“无法从未定义中获取”错误.

TypeError: Cannot read property ‘NavBar’ of undefined
[0] at 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>
);

root package.json:

{
  "name": "project",
  "version": "1.0.0",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

UI package.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"
  }
}

web app package.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"
  ]
}

生成的汇总代码看起来没问题,所以我认为这是一个纱线问题,但我不确定.任何帮助,将不胜感激!

问候

最佳答案 问题必须在于您使用babel /汇总来解释代码的方式.我有一个关于代码在
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’](当我调试你的例子时,我得到导出[‘default’]是未定义的,因此你得到错误无法读取属性未定义[0]的’NavBar’,因为您将undefined传递给exports.

这是通过插件’add-module-exports’完成的,如果你真的需要module.exports(除非存在NodeJS或某些RequireJS,否则不需要).

为了使其工作,只需从项目-ui .babelrc中的插件中删除“add-module-exports”.

点赞