如何将React组件导出为NPM包以在单独的项目中使用?

Ale*_*ach 4 javascript npm ecmascript-6 reactjs webpack

我在项目中创建了一个React组件,我想在多个项目中使用它.目前,我只关心在本地和发展中做这件事.React组件被渲染到根div中,项目使用webpack和babel将JSX,ES6和一些ES7功能转换成一个包.

我认为导出这个组件会很简单,这样我就可以npm install MyComponent在一个新项目中运行并开始使用它.但是,我发现它并不是那么直截了当.特别是,我已经阅读了几个小时和几个小时,似乎只是变得更加困惑.

如果我的最终目标是在其包含的项目中继续开发'MyComponent',而在任何其他本地项目中使用'MyComponent',我的选择是什么?我做的第一件事就是改变main我的钥匙package.json/src/components/MyComponent和运行npm pack.这会产生一个tgz我可以通过其绝对文件路径安装在其他项目中的文件.但是,我发现es6和jsx没有被编译,因此我的客户端项目无法解析MyComponent.然后我使用webpack进入lib/MyComponent,但是当我import MyComponent from './path/to/MyComponent-1.0.0.tgz{}在控制台中看到(一个空对象)时.

寻找我的问题的解决方案出现了许多不同的方法,将NPM,Grunt,Gulp,Babel,Webpack等组合在一起.而且我担心它会花费更多的时间(几天?)才能将其研磨成可以理解的东西.

鉴于我的要求,我可以实现的最简单的解决方案是:1)将我的React组件编译成最简单的导入模块2)将其导入任何本地项目3)继续在原始主机项目中开发包并轻松更改传播到客户项目.

Tro*_*ord 6

一般来说,如果你要开始创建React组件分离包(这是一个伟大的图案,你已经提到的所有原因) -你将需要得到至少有点熟悉webpackbabel.这里要学到很多东西,但让我试着指出你正确的方向:

// webpack.config.js

/* eslint-disable */
const path = require('path')
const webpack = require('webpack')

const ENVIRONMENT = process.env.NODE_ENV
const PRODUCTION = ENVIRONMENT === 'production'
const SOURCEMAP = !PRODUCTION || process.env.SOURCEMAP

const library = 'your-lib-name' // << RENAME THIS <<
const filename = PRODUCTION ? `${library}.min.js` : `${library}.js`

const plugins = []

if (PRODUCTION) {
  plugins.push(
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(ENVIRONMENT),
    }),
    new webpack.optimize.ModuleConcatenationPlugin(),
    new webpack.optimize.UglifyJsPlugin({
      minimize: true,
      output: { comments: false, semicolons: false },
      sourceMap: SOURCEMAP,
    })
  )
}

module.exports = {
  devtool: SOURCEMAP ? 'source-map' : 'none',
  entry:  `${__dirname}/path/to/your/component.js`, // << RENAME THIS <<
  externals: {
    'react': 'react',
    'react-dom': 'react-dom',
  },
  module: {
    loaders: [{
      test:    /\.js$/,
      loader:  'babel-loader',
      exclude: /node_modules/,
    }],
  },
  output: {
    filename,
    library,
    path:           `${__dirname}/lib`,
    libraryTarget:  'umd',
    umdNamedDefine: true,
  },
  plugins,
}
Run Code Online (Sandbox Code Playgroud)

我知道这看起来像一堆 - 但它处理了你想要的大部分.具体来说:

  1. 如果您指定NODE_ENV=production何时构建,这将使您的包裹丑化/缩小,并进行其他一些您可能需要的修剪.
  2. 使用此脚本构建将输出一个sourcemap,您可以使用dev工具在调试器窗口中检查缩小的代码等.
  3. 这标志着react,并react-dom作为externals-这意味着他们将不会被捆绑起来,包装的包.这很棒 - 因为这意味着你不会react因为import编辑自己的组件而获得2+份文件大小!

但是,要使用它,你现在需要一些package.json爱.

package.json

{
  "name": "Your Name",
  "version": "0.0.1",
  "description": "This is my awesome react package!",
  "main": "path/to/your/component.js",
  "author": "Your Name",
  "license": "MIT",
  "repository": { /* Your Repo Info Here */ },
  "dependencies": {
    "any-packages-you-need-included-in-builds": "^1.0.0"
  },
  "devDependencies": {
    "babel-cli": "^6.22.2",
    "babel-loader": "^7.1.0",
    "babel-preset-es2015": "^6.22.0",
    "babel-preset-react": "^6.22.0",
    "prop-types": "^15.5.10",
    "react-dom": "^15.6.1",
    "webpack": "^3.0.0"
  },
  "scripts": {
    "build": "yarn prebuild && NODE_ENV=production webpack",
    "prebuild": "mkdir -p ./lib && rm -rf ./lib/*"
  }
}
Run Code Online (Sandbox Code Playgroud)

很明显,你可以有更多的在这里,如果你需要它-比如其他babel-plugin-*您在transpilation使用插件,其他包,etc.But这集将让你的webpack构建运行.请注意,这里的脚本假设您正在使用yarn- 这样您就可以运行yarn build,并且您在posix系统上运行mkdir.如果您使用的是Windows或不使用yarn,请相应地更新脚本.

其余的只是学习将包发布到npm另一个包存储库.首先,这只是将version数字设置为package.jsonnew(npm version)然后发布(npm publish).当然,您必须有一个npm帐户 - 并登录(npm login).

一旦你发表了就npm可以了yarn add your-package-name.

请记住,虽然-我们标记reactreact-dom作为external-所以在消费包,你需要确保他们可以作为window.Reactwindow.ReactDOM-或者你需要直接从包括组件node_modules/your-package-name/path/to/your/component.js


Sid*_*ney 4

您不需要npm pack包即可使用它。如果您将组件制作成 git 存储库并将其放在 Github 上,则可以使用 NPM 直接从 Github 安装它,方法是使用npm install alex/mycomponentwherealex是您的 github 用户名,mycomponent是存储库名称。重新运行该命令将从 Github 重新安装,以防您对存储库进行更改。

一旦您对该组件感到满意,您可以将其上传到 NPM 注册表,以便像任何其他包一样安装 ( npm install name)。首先使用 Github 会让开发变得更容易一些。

默认情况下,Webpack 可能不会编译内容node_modules。通常,包在发布之前会被预编译,但您应该能够配置 webpack 来构建“打包”组件以及应用程序的其余部分。也许这会有所帮助:https ://stackoverflow.com/a/38008149/7486612