提问者:小点点

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


我在一个项目中创建了一个React组件,我想在多个项目中使用它。目前,我只关心在当地和为了发展而这样做。React组件被呈现到根div中,该项目使用webpack和babel将JSX、ES6和一些ES7特性转换成一个包。

我认为导出这个组件很简单,这样我就可以简单地运行npm安装MyComponent并开始在一个新的项目中使用它。然而,我发现这并不简单。尤其是,我已经读了几个小时又几个小时,似乎越来越困惑。

如果我的最终目标是在包含“MyComponent”的项目中继续开发“MyComponent”,同时在任何数量的其他本地项目中使用“MyComponent”,那么我的选择是什么?我做的第一件事是更改我的包的main键。json/src/components/MyComponent并运行npm-pack。这将生成一个tgz文件,我可以通过它的绝对文件路径在其他项目中安装它。但是,我发现es6和jsx没有被传输,因此我的客户机项目将无法解析MyComponent。然后,我使用webpack将MyComponent转换为lib/MyComponent,但当我从导入MyComponent时/路径/to/MyComponent-1.0。tgz我只能在控制台中看到{}(一个空对象)。

寻找我的问题的解决方案会出现许多不同的方法,包括NPM、Grunt、Gulp、Babel、Webpack等。。我担心会有更多的小时(天?)在我能把它变成可以理解的东西之前。

考虑到我的需求,我可以实现的最简单的解决方案是什么1)将我的React Component编译到最简单的导入模块2)将其导入到任何本地项目3)继续在原始主机项目中开发包,并使更改易于传播到客户项目。


共3个答案

匿名用户

一般来说,如果您要开始创建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,
}

我知道这看起来像一堆——但它能处理你想要的大部分东西。具体而言:

  1. 如果您在构建时指定NODE_ENV=生产,这将丑化/缩小您的包,并执行稍后可能需要的其他修剪。
  2. 使用此脚本构建将输出一个源地图,您可以将其与开发工具一起使用,以便在调试器窗口中检查您的小型代码。
  3. 这将react-domreact-dom标记为外部文件-这意味着它们不会被捆绑并打包在您的捆绑包中。这是伟大的-因为这意味着你不会得到2个副本的反应的文件大小,仅仅因为你已经导入了你自己的组件!

不过,要使用它,您现在需要一些包。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/*"
  }
}

显然,如果你需要,你可以在这里有更多的东西——比如你在转置、其他包等中使用的其他Babel-plugin-*插件。但是这个设置会让你的webpack构建运行。请注意,这里的脚本假设您正在使用yarn-这样您就可以运行yarn build,并且您在一个posx系统上,以便mkdir工作。如果您在windows上或者不使用yarn,只需相应地更新脚本。

剩下的只是学习将包发布到npm或其他包存储库。主要是在包中设置版本号。json到新的内容(npm版本),然后发布(npm发布)。当然,您必须拥有一个npm帐户,并且必须登录(npm login)。

发布到npm后,只需添加包名即可。

请记住,我们将reactreact dom标记为external,因此在消费包中,您需要确保它们作为窗口可用。反应窗口。ReactDOM-或者您需要直接从节点\模块/您的包名/路径/到/您的/组件中包含组件。js

匿名用户

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

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

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

匿名用户

为了将react库推送到NPM中,您可能需要一些样板文件来为您安装和转换许多东西(您仍然可以使用当前的react模块作为主要来源,只需按照我答案末尾的指南进行操作,那么您肯定会得到所有的想法)

或者你也可以参考我以前对一个类似问题的回答:发布到npm的问题

=====

我还成功地将几个react库推入NPM:

https://www.npmjs.com/~thinhvo0108

=====

您的github存储库的文件夹结构也应该与我的类似:

https://github.com/thinhvo0108/react-paypal-express-checkout

=====

以下是有用的教程:

(样板资料来源)https://github.com/juliancwirko/react-npm-boilerplate

(作者文章)http://julian.io/creating-react-npm-packages-with-es2015/