import undefined при объединении библиотеки пользовательского интерфейса с объединением с использованием рабочих пространств пряжи

Для нового проекта я начал использовать свертку, чтобы связать библиотеку пользовательского интерфейса и использовать эту библиотеку в приложении реакции. Я также использую рабочие области пряжи для управления внутренними зависимостями между библиотекой пользовательского интерфейса и веб-приложением.

Когда я пытаюсь использовать библиотеку пользовательского интерфейса в своем веб-приложении, импорт возвращает значение undefined и выдает ошибку «невозможно получить из неопределенного».

TypeError: невозможно прочитать свойство «NavBar» неопределенного [0] в приложении (C: /Users/user/dev/project/packages/project-web/src/pages/App.jsx: 9: 6)

Код веб-приложения:

import React from 'react';
import {NavBar} from 'project-ui';

const App = () => (
  <div>
    <NavBar/>

    <div>App component!x</div>
  </div>
);

корневой 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"
  }
}

веб-приложение 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"
  ]
}

Сгенерированный код объединения выглядит нормально, поэтому я думаю, что это проблема пряжи, но я не уверен. Любая помощь будет оценена по достоинству!

С уважением, Корнел


person Cornel Janssen    schedule 25.06.2018    source источник
comment
Что возвращает exports['default']? ;)   -  person GuyT    schedule 28.06.2018
comment
Не могли бы вы опубликовать исходный код для NavBar (без кода, созданного из RollUp)   -  person SirPeople    schedule 29.06.2018
comment
Кроме того, не могли бы вы опубликовать свою конфигурацию babel? Я никак не мог получить тот же код, что и вы, после его создания, и это могло быть проблемой   -  person SirPeople    schedule 29.06.2018
comment
Я добавил исходный код и конфигурацию babel. Спасибо за ответы!   -  person Cornel Janssen    schedule 29.06.2018
comment
@GuyT значение экспорта ['default'] равно {NavBar: [Function: NavBar]}, когда я добавляю журнал в конец сгенерированного кода.   -  person Cornel Janssen    schedule 29.06.2018


Ответы (1)


Проблема должна быть в том, как вы переносите код с помощью babel / rollup. У меня есть живой пример в том, как ваш код должен выглядеть в

Сгенерированный код для меня:

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 ['defaults'] (когда я отлаживаю ваш пример, я получаю, что export['default'] is undefined, следовательно, вы получаете ошибку Cannot read property 'NavBar' of undefined [0], поскольку вы передаете undefined в экспорт.

Это делается с помощью плагина add-module-exports, который необходим, если вам действительно нужен module.exports (в этом нет необходимости, если не присутствует NodeJS или какой-либо RequireJS).

Чтобы он заработал, просто удалите "add-module-exports" из своих плагинов в project-ui .babelrc.

person SirPeople    schedule 29.06.2018
comment
Спасибо за помощь! - person Cornel Janssen; 29.06.2018