资讯专栏INFORMATION COLUMN

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

junfeng777 / 1017人阅读

摘要:从搭建脚手架到在上发布组件最近公司给公司里架设了私有的仓库,相应地也需要一个用来发布组件用的脚手架,在这个过程中又又又又复习了一下,在这里分享下脚手架搭建的过程。

从搭建脚手架到在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 (
A new Component
) } }

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




    
    Title


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 

组件预览:

} ReactDom.render(, 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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100845.html

相关文章

  • 简易手架搭建

    摘要:总结以上就是一个简单脚手架的实现方式,后期也会一直去更新和维护这个脚手架,公司现在新的项目就是基于这个脚手架去搭建的,因为公司现在的项目都是写的,所以的功能暂时不支持,后期也会慢慢支持 写在最前面 随着公司业务的发展,独立的系统也慢慢多了起来,脚手架的必要性也日趋明显。 基于此,便开始搭起了脚手架,主要解决两个问题: 1.项目的反复配置 2.公共组件的自动更新 代码地址点这里,可以...

    cyixlq 评论0 收藏0
  • 1 到完美,写一个 js 库、node 库、前端组件

    摘要:从到完美,写一个库库前端组件库之前讲了很多关于项目工程化前端架构前端构建等方面的技术,这次说说怎么写一个完美的第三方库。使用导出模块,就可以在使用这个库的项目中构建时使用功能。 从 1 到完美,写一个 js 库、node 库、前端组件库 之前讲了很多关于项目工程化、前端架构、前端构建等方面的技术,这次说说怎么写一个完美的第三方库。 1. 选择合适的规范来写代码 js 模块化的发展大致有...

    rollback 评论0 收藏0
  • 1 到完美,写一个 js 库、node 库、前端组件

    摘要:从到完美,写一个库库前端组件库之前讲了很多关于项目工程化前端架构前端构建等方面的技术,这次说说怎么写一个完美的第三方库。使用导出模块,就可以在使用这个库的项目中构建时使用功能。 从 1 到完美,写一个 js 库、node 库、前端组件库 之前讲了很多关于项目工程化、前端架构、前端构建等方面的技术,这次说说怎么写一个完美的第三方库。 1. 选择合适的规范来写代码 js 模块化的发展大致有...

    xiaolinbang 评论0 收藏0
  • 使用prince-cli,轻松构建高性能React SPA项目~

    摘要:对模块进行了打包,监听文件更改刷新等功能,创建了个服务,分别为静态资源服务用于代理本地资源,与自刷新浏览器请求服务用于接受,请求,返回数据服务用于收发消息。除了项目,还可以换成项目。项目地址如果觉得对你有所帮助,多谢支持 prince-cli 快速指南 这是一个为快速创建SPA所设计的脚手架,旨在为开发人员提供简单规范的开发方式、服务端环境、与接近native应用的体验。使用它你能够获...

    roundstones 评论0 收藏0
  • 0 到 1 再到 100, 搭建、编写、构建一个前端项目

    摘要:从到再到搭建编写构建一个前端项目选择现成的项目模板还是自己搭建项目骨架搭建一个前端项目的方式有两种选择现成的项目模板自己搭建项目骨架。使用版本控制系统管理源代码项目搭建好后,需要一个版本控制系统来管理源代码。 从 0 到 1 再到 100, 搭建、编写、构建一个前端项目 1. 选择现成的项目模板还是自己搭建项目骨架 搭建一个前端项目的方式有两种:选择现成的项目模板、自己搭建项目骨架。 ...

    call_me_R 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<