从搭建脚手架到在npm上宣布react组件

从搭建脚手架到在npm上宣布react组件

近来公司给公司里架设了私有的npm堆栈,响应地也须要一个用来宣布react组件用的脚手架,在这个历程当中又又又又温习了一下webpack,在这里分享下脚手架搭建的历程。

起首,我们预期的脚手架具有以下功用

  • 开辟组件时能够及时预览
  • 对组件种种资本举行打包(js/css/图片等)
  • 一键打包宣布

1.竖立项目

脚手架的名字暂时取react-simple-component-boilerplate

起首竖立一个新目次用于放我们的文件:

mkdir react-simple-component-boilerplate
cd react-simple-component-boilerplate

运用npm敕令竖立一个项目

npm init

接下来会提醒你输入项目的称号、版本号、作者等,也能够一起回车,稍后修正。
这一步完成后,你的项目文件夹里应该有一个package.json文件了,这个文件保留了我们项目和组件的种种信息。

接下来竖立以下的目次构造

react-simple-component-boilerplate
    |-- config // webpack设置
    |-- demo    // 开辟时预览用
    |-- dist    // 打包结果
    |-- src     // 源文件目次
        | -- assets // 寄存图片等媒体文件
        | -- style    // 寄存款式,项目运用的是less来编写款式

2.装置依靠

既然我们要宣布的是react组件,那依靠里一定少不了react。
运用npm install装置下面的依靠

npm install react react-dom --save

打包东西挑选的是webpack,下面是开辟依靠,也须要一并装置

  "devDependencies": {
    // babel用于将你写的es6+的代码转换到es5
    "@babel/cli": "^7.0.0",
    "@babel/core": "^7.0.0",
    "@babel/plugin-proposal-class-properties": "^7.0.0", // 用于支撑class属性
    "@babel/plugin-proposal-decorators": "^7.0.0", // 支撑decorator
    "@babel/plugin-transform-modules-commonjs": "^7.0.0",
    "@babel/plugin-transform-runtime": "^7.0.0", // 自动polyfill es5不支撑的api特征
    "@babel/preset-env": "^7.0.0", // 依据目的环境来按需转码
    "@babel/preset-react": "^7.0.0", // 让babel支撑react语法
    "babel-loader": "^8.0.0",
    "css-loader": "^1.0.0",
    "file-loader": "^2.0.0",
    "html-loader": "^0.4.4",
    "less-loader": "^4.1.0", // 运用less来编写款式
    "mini-css-extract-plugin": "^0.5.0", // 将css提取成一个零丁的文件
    "style-loader": "^0.23.0",
    "webpack": "^4.26.0",
    "webpack-cli": "^3.1.2", // webpack4以后须要分外装置webpack-cli
    "webpack-dev-server": "^3.1.14", // 开辟时预览组件所用的效劳,在文件变化时会自动革新页面
    "webpack-merge": "^4.1.4" // 用于兼并webpack设置
  },

3.编写组件

/src目次下新建一个index.js,这就是我们组件的进口文件了。
假如项目中要运用图片、css等,分类放到assetsstyle文件夹下就好。

下面我们就在index.js中写一个简朴的组件

/* src/index.js */

import React from 'react';
import './style/style.less'; // 运用less的状况
import testPng from './assets/test.png'; // 运用图片的状况

export default class MyComponent extends Component {
    render(){
        return (<div>A new Component</div>)
    }
}

接下来,我们在/demo目次下新建index.htmldemo.js这两个文件用于在开辟组件时预览组件结果。
index.html内容以下

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="root"></div>
<script src="demo.bundle.js"></script>
</body>
</html>

demo.js中,我们要运用一下方才写的组件(位于/src/index.js)看一下结果,开辟中这个demo.js文件会被打包成demo.bundle.js,就是在上面index.html中援用的js。

import React from 'react';
import ReactDom from 'react-dom';
import MyComponent from '../src/index'

const Demo  = () => {
  return <div>
    <h1>组件预览:</h1>
    <MyComponent />
  </div>
}

ReactDom.render(<Demo />, document.getElementById('root'));

4.设置webpack和babel

4.1 设置webpack

/config下我们竖立三个webpack设置文件

  • webpack.base.js
  • webpack.config.dev.js // 开辟时的设置
  • webpack.config.prod.js // 打包宣布时的设置

因为开辟和宣布打包时webpack的设置有一部份是大众而且反复的,我们把这部份的设置零丁拿出来放到webpack.base.js中。
起首是大众设置webpack.base.js:

module.exports = {
  module: {
    rules: [
      { // 在webpack中运用babel须要babel-loader
        test: /\.js?$/,
        loader: 'babel-loader',
        exclude: '/node_modules/',
      },
      { // 用于加载组件或许css中运用的图片
        test: /\.(jpg|jpeg|png|gif|cur|ico|svg)$/,
        use: [{
          loader: 'file-loader', options: {
            name: "images/[name][hash:8].[ext]"
          }
        }]
      }
    ]
  }
}

下面是开辟时所用的webpack设置,写在webpack.config.dev.js

const path = require('path');
const merge = require('webpack-merge');
const baseConfig = require('./webpack.base.js'); // 援用大众的设置

const devConfig = {
  entry: './demo/demo.js', // 进口文件
  mode: 'development', // 打包为开辟形式
  output: {
    filename: 'demo.bundle.js', // 输出的文件称号
    path: path.resolve(__dirname, '../demo') // 输出的文件目次
  },
  devServer: { // 该字段用于设置webpack-dev-server
    contentBase: path.join(__dirname, '../demo'),
    compress: true,
    port: 9000, // 端口9000
    open: true // 自动翻开浏览器
  },
  module: {
    rules: [
      { // 编译less
        test: /\.less$/,
        exclude: '/node_modules/',
        use: [{
          loader: 'style-loader'
        }, {
          loader: 'css-loader'
        }, {
          loader: 'less-loader'
        }]
      },
    ]
  },
}

module.exports = merge(devConfig, baseConfig); // 将baseConfig和devConfig兼并为一个设置

须要注重的是,等会运用webpack-dev-sevrer启动开辟效劳时,并不会现实在demo文件夹下天生demo.bundle.js,打包好的文件是在内存中的,但并不影响我们运用。

下面是打包宣布时所用的webpack设置,写在webpack.config.prod.js

const path = require('path');
const merge = require('webpack-merge');
const baseConfig = require('./webpack.base.js');
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 用于将组件的css打包成零丁的文件输出到`dist`目次中

const devConfig = {
  entry: './src/index.js',
  mode: 'production',
  output: {
    path: path.resolve(__dirname, '../dist'),
    filename: 'index.js', // 输出文件
    libraryTarget: 'umd', // 采纳通用模块定义, 注重webpack到4.0为止依旧不供应输出es module的要领,所以输出的结果必需运用npm装置到node_modules里再用,不然会报错
    library: 'react-simple-component-boilerplate', // 库称号
    libraryExport: 'default', // 兼容 ES6(ES2015) 的模块体系、CommonJS 和 AMD 模块范例
  },
  externals: {
    react: {
      root: "React",
      commonjs2: "react",
      commonjs: "react",
      amd: "react"
    },
    "react-dom": {
      root: "ReactDOM",
      commonjs2: "react-dom",
      commonjs: "react-dom",
      amd: "react-dom"
    }
  },
  module: {
    rules: [{
      test: /\.(le|c)ss$/,
      use: [
        MiniCssExtractPlugin.loader,
        "css-loader",
        {
          loader: "less-loader",
          options: {
            sourceMap: false
          }
        }
      ]
    }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "main.min.css" // 提取后的css的文件名
    })
  ],
}

module.exports = merge(devConfig, baseConfig);

上面我们设置了externals字段,这一点异常重要。
externals定义了外部依靠。将react和react-dom增加进该字段,申明我们的组件将依靠外部的react和react-dom,如许就能够防止把react和react-dom打包进去(不然组件会很大)

4.1 设置babel
我们须要用babel把我们的代码编译成es5版本。在项目根目次新建一个.babelrc文件,输入以下内容。

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": "> 0.25%, not dead"
      }
    ],
    "@babel/preset-react"
  ],
  "plugins": [
    "@babel/plugin-transform-runtime",
    "@babel/plugin-transform-modules-commonjs",
    [
      "@babel/plugin-proposal-decorators",
      {
        "legacy": true
      }
    ],
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-object-rest-spread"
  ]
}

我们在presets个中运用了preset-env, 划定了输出的代码目的环境是份额大于0.25%的浏览器。别的因为我们的项目里运用了reactpresets中就要到场preset-react
同时,plugins设置了一些babel插件,用于支撑装潢器睁开操作符等类内直接定义属性等新的es特征。

4.3 设置启动敕令
我们再次回到项目根目次下的package.json中,编辑以下

  "scripts": {
    "build": "set NODE_ENV=production && webpack --config ./config/webpack.config.prod.js",
    "pub": "npm run build && npm publish",
    "dev": "webpack-dev-server --config ./config/webpack.config.dev.js"
  },
  "main": "dist/index.js",
  "files": ["dist"]
  • build 敕令用于打包组件
  • dev 敕令会运用webpack-dev-server启动一个开辟效劳用于预览组件结果
  • pub 敕令举行打包组件而且宣布到npm上

main字段指定了我们的组件的进口文件,files字段用于指定我们的npm包的文件目次。

5.试用和宣布

要宣布一个npm包,我们需运用以下敕令增加一个npm的账号,假如已增加过的这一步能够跳过。

npm adduser

假如已有npm账号,能够运用npm login上岸。
假如不知道本身是不是已增加过了npm账号,运用npm whoami检察上岸信息即可

接下来就编辑package.json把组件的称号/版本/引见等字段都填写一下。

好了,接下我们先运用npm run dev敕令,此时会自动翻开默许浏览器预览组件。
假如没什么题目的话,接下来运用npm run pub举行打包和宣布。
守候宣布完成后,我们就下载装置一下。

npm i your-component // 假定你的包名字叫your-component

运用本身宣布的组件

import YourComponent from 'your-component';
import 'your-component/dist/main.min.css'; // 假如给组件写了款式,须要手动导入css文件

6.总结

到这里,一个异常异常简朴的用于宣布react小组件的脚手架就搭好了,总结一下个中要注重的处所:

  • webpack打包时libraryTarget要运用umd
  • externals 里要把外部依靠设置好
  • 假如还要天生es module,能够分外运用gulp或rollup等东西
  • webpack4 以后发起运用MiniCssExtractPlugin来提取css
    原文作者:JohnSnow
    原文地址: https://segmentfault.com/a/1190000017826273
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞