我在一个项目中创建了一个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)继续在原始主机项目中开发包,并使更改易于传播到客户项目。
一般来说,如果您要开始创建React
组件作为独立的包(这是一个很好的模式,因为您已经提到了所有的原因)-您需要至少对webpack
和babel
有一点熟悉。这里有很多东西需要学习,但让我试着为您指出正确的方向:
// 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,
}
我知道这看起来像一堆——但它能处理你想要的大部分东西。具体而言:
NODE_ENV=生产
,这将丑化/缩小您的包,并执行稍后可能需要的其他修剪。源地图
,您可以将其与开发工具一起使用,以便在调试器窗口中检查您的小型代码。react-dom
和react-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
或其他包存储库。主要是在包中设置
到新的内容(版本
号。jsonnpm版本
),然后发布(npm发布
)。当然,您必须拥有一个npm
帐户,并且必须登录(npm login
)。
发布到npm
后,只需添加包名即可。
请记住,我们将react
和react 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/