IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 前端组件化实践(bookstory+rollup+lerna+typescript)-react组件 -> 正文阅读

[JavaScript知识库]前端组件化实践(bookstory+rollup+lerna+typescript)-react组件

前期准备:

需要有一个github或者gitlab账号的代码仓库,还要有一个npm仓库的账号。这两个账号公网或者私网都可以。


创建项目

新建一个项目,我是在github上创建的测试项目,可以随意发挥:

克隆项目到文件夹,我这里克隆到了D:\webPro。

cmd进入到D:\webPro,执行等等安装完成:

npx create-react-app cookie-test-pkg --template typescript

?搭建 storybook react环境

npx -p @storybook/cli sb init --type react

?项目中会多出.storybook和src/stories目录

?执行?

?npm run storybook

?会启动storybook界面,如下图所示:

使用Lerna来管理包?

全局安装lerna

npm install lerna -g

?lerna init

?

?创建一个包,我这里定义一个叫cookieButton,会发现packages多了一个目录

?lerna create?cookieButton

?

?为了支持typescript,还需要单独安装相关插件依赖

npm install -D @storybook/preset-create-react-app @storybook/react

?将lib重命名为src,因为之后打包想使用lib目录名,故此修改(不改也是可以的)

根据目录增加以下文件

文件代码,自取:

//src/CookieButtuon.tsx

import React from 'react'
import './CookieButton.scss'
export interface ButtonProp {
  bgcolor: String
  color: String
  name: String
}
function CookieButton({ bgcolor, color, btnname }) {
  return (
    <button
      className="cookie-btn"
      style={{ color: color, backgroundColor: bgcolor }}
    >
      {btnname}
    </button>
  )
}

export default CookieButton
// src/CookieButton.scss

.cookie-btn {
  position: relative;
  display: block;
  box-sizing: border-box;
  text-align: center;
  text-decoration: none;
  line-height: 1.35;
  -webkit-tap-highlight-color: transparent;
  overflow: hidden;
}
//src/index.tsx

import CookieButton, { ButtonProp } from './CookieButton'

export { CookieButton, ButtonProp }
// src/index.stories.tsx

import React from 'react'
import { ComponentStory, ComponentMeta } from '@storybook/react'
import { CookieButton } from './index'

export default {
  title: 'CookieButton',
  component: CookieButton,
} as ComponentMeta<typeof CookieButton>

//storybook 定义的一种args写法,可以在界面生成配置界面
const Template: ComponentStory<typeof CookieButton> = (args) => (
  <CookieButton {...args} />
)

//示例一
export const defaultButton = Template.bind({})
defaultButton.args = {
  bgcolor: '#f0f0f0',
  color: '#000000',
  btnname: '按钮',
}

//示例二
export const BlackButton = Template.bind({})
BlackButton.args = {
  bgcolor: '#333333',
  color: '#ffffff',
  btnname: '按钮',
}

由于我们的项目用tsx编写,需要增加支出ts的插件

npm install -D @storybook/preset-scss css-loader sass sass-loader style-loader

修改 .storybook/main.js


?

再次启动项目,能启动起来,表示正常

?组件已经有了,准备打包

?打包我这边使用rollup,后续会列一下它和webpack的区别。

安装rollup以及相关依赖

npm install -D rollup rollup-plugin-babel rollup-plugin-commonjs rollup-plugin-node-resolve rollup-plugin-replace @rollup/plugin-image rollup-plugin-terser rollup-plugin-postcss postcss cssnano postcss-nested postcss-simple-vars

?安装好rollup后还需要配置babel,也需要安装babel配置需要的相关插件依赖

npm install -D @babel/cli @babel/core @babel/plugin-external-helpers @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-proposal-object-rest-spread @babel/plugin-transform-react-jsx @babel/plugin-transform-runtime @babel/preset-env @babel/preset-react @babel/preset-typescript

?安装cross-env等依赖

npm install -D cross-env?rollup-plugin-typescript2?@rollup/plugin-json?rollup-plugin-dts

?

//rollup.config.js

// Rollup plugins
// babel插件用于处理es6代码的转换,使转换出来的代码可以用于不支持es6的环境使用
import babel from 'rollup-plugin-babel'
// resolve将我们编写的源码与依赖的第三方库进行合并
import resolve from 'rollup-plugin-node-resolve'
// 解决rollup.js无法识别CommonJS模块
import commonjs from 'rollup-plugin-commonjs'
// 全局替换变量比如process.env
import replace from 'rollup-plugin-replace'
// 使rollup可以使用postCss处理样式文件scss、css等
import postcss from 'rollup-plugin-postcss'
import autoprefixer from 'autoprefixer'
// 可以处理组件中import图片的方式,将图片转换成base64格式,但会增加打包体积,适用于小图标
import image from '@rollup/plugin-image'
// 压缩打包代码(这里弃用因为该插件不能识别es的语法,所以采用terser替代)
// import { uglify } from 'rollup-plugin-uglify';
// 压缩打包代码
import { terser } from 'rollup-plugin-terser'
// PostCSS plugins 处理css定义的变量
import simplevars from 'postcss-simple-vars'
// 处理scss嵌套样式写法
import nested from 'postcss-nested'
// 替代cssnext
import postcssPresetEnv from 'postcss-preset-env'
// css代码压缩
import cssnano from 'cssnano'
// 支持typescript
import typescript from 'rollup-plugin-typescript2'
// 支持rollup.js导入json模块
import json from '@rollup/plugin-json'
// 用于打包生成*.d.ts文件
import dts from 'rollup-plugin-dts'
// 引入package
// import pkg from "./package.json";

const env = process.env.NODE_ENV
const PACKAGE_ROOT_PATH = process.cwd()

const config = [
  {
    // 入口文件我这里在components下统一导出所有自定义的组件
    input: `${PACKAGE_ROOT_PATH}/src/index.tsx`,
    // 输出文件夹,可以是个数组输出不同格式(umd,cjs,esm...)通过env是否是生产环境打包来决定文件命名是否是.min
    output: [
      {
        file: `${PACKAGE_ROOT_PATH}/dist/index.esm.js`,
        format: 'esm',
      },
      {
        file: `${PACKAGE_ROOT_PATH}/dist/index.js`,
        format: 'cjs',
      },
    ],
    // 注入全局变量比如jQuery的$这里只是尝试 并未启用
    // globals: {
    //   react: 'React',                                         // 这跟external 是配套使用的,指明global.React即是外部依赖react
    //   antd: 'antd'
    // },
    // 自定义警告事件,这里由于会报THIS_IS_UNDEFINED警告,这里手动过滤掉
    onwarn: function (warning) {
      if (warning.code === 'THIS_IS_UNDEFINED') {
        return
      }
    },
    // 将模块视为外部模块,不会打包在库中
    external: ['react', 'react-dom'],
    // 插件
    plugins: [
      typescript(),
      image(),
      postcss({
        plugins: [
          simplevars(),
          nested(),
          postcssPresetEnv(),
          autoprefixer(),
          cssnano(),
        ],
        // 处理.css和.scss文件
        extensions: ['.css', '.scss'],
      }),
      // 告诉 Rollup 如何查找外部模块并安装它
      resolve(),
      // babel处理不包含node_modules文件的所有js,ts,tsx
      babel({
        exclude: 'node_modules/**',
        runtimeHelpers: true,
        plugins: ['@babel/plugin-external-helpers'],
        extensions: ['.js', '.ts', 'tsx'],
      }),
      // 将 CommonJS 转换成 ES2015 模块
      // 这里有些引入使用某个库的api但报未导出该api通过namedExports来手动导出
      commonjs({
        namedExports: {
          'node_modules/react-is/index.js': ['isFragment'],
          'node_modules/react/index.js': [
            'Fragment',
            'cloneElement',
            'isValidElement',
            'Children',
            'createContext',
            'Component',
            'useRef',
            'useImperativeHandle',
            'forwardRef',
            'useState',
            'useEffect',
            'useMemo',
          ],
          'node_modules/react-dom/index.js': [
            'render',
            'unmountComponentAtNode',
            'findDOMNode',
          ],
          'node_modules/gojs/release/go.js': [
            'Diagram',
            'GraphLinksModel',
            'Overview',
            'Spot',
          ],
        },
      }),
      json(),
      // 全局替换NODE_ENV,exclude表示不包含某些文件夹下的文件
      replace({
        // exclude: 'node_modules/**',
        'process.env.NODE_ENV': JSON.stringify(env || 'development'),
      }),
      // 生产环境执行terser压缩代码
      env === 'production' && terser(),
    ],
  },
  {
    // 打包*.d.ts配置,用于支持typescript项目
    input: `${PACKAGE_ROOT_PATH}/src/index.tsx`,
    output: [
      {
        file: `${PACKAGE_ROOT_PATH}/dist/index.d.ts`,
        format: 'esm',
      },
    ],
    external: [/\.scss$/, /\.css$/],
    plugins: [dts()],
  },
]

export default config

?修改tsconfig.json

?

??修改.gitignore,将package下打包目录忽略

node_modules

.DS_Store
lerna-debug.log
yarn-error.log

packages/*/dist
packages/*/lib

storybook-static

给每个包的package.json下增加scripts:

"scripts": {
    "build:sit": "cross-env BABEL_ENV=rollup rollup -c ../../rollup.config.js",
    "build": "cross-env NODE_ENV=production rollup -c ../../rollup.config.js"
  },

??跟目录的package.json的scripts下增加

"build": "lerna run build",?

?执行打包命令

npm run build //实际会到每个package下执行build

?将代码提交到github上

git add .

git commit -m XXX

git push

?发包到仓库

lerna publish

登录仓库看到成功发包啦

?在其他项目中使用:

npm install cookiebutton?

如果是私有仓库,记得修改仓库地址哦。

?!!!注意事项!!!

如果package.json没有配置发布仓库,可以手动切换

? ? npm config set registry=https://registry.npmjs.org/

例如第一次切换公网后,进行下初始化账号

? ?git login? //输入账号、秘密、邮箱、邮箱收到的验证码

?每次发包,git记录一定要有变化哦,而且发布的的版本号要递增,否则是发布不上的。

相关文档推荐:

Storybook官网

Lerna官网

Rollup官网

?


一些补充:

1、关于 webpack和rollup打包的优劣

2、增加eslint和prettier:用于规范代码

代码检查借助Prettier以及ESLint的扩展,eslint-config-prettier将关闭所有不必要的或可能与Prettier冲突的规则。eslint-plugin-prettier则是添加Prettier格式设置规则的插件。

yarn add -D eslint prettier eslint-config-prettier eslint-plugin-prettier eslint-plugin-react

3、增加plop:用于组件模板创建(在上面项目中我没有用到,是用lerna create创建的)

yarn add -D plop

详细配置可以查看官网Plop

package.json中增加相应scripts

“plop”: "plop",

创建plopfile.js,并创建模板文件(模板文件和要生成的文件路由和名字都可以自定义)

module.exports = function (plop) {
  // create your generators here
  plop.setGenerator('basics', { //basics是生成的文件夹名
    description: 'this is a component',
    prompts: [  // 提示问题,可以是多问题,以数组的形式表示
      {  // 可以根据输入的name动态创建组件的相关文件
        type: 'input',
        name: 'name',
        message: 'please input component name',
      },
    ],
    actions: [  // 命令完成对应的操作,可以是多操作,以数组的形式表示
      {
        type: 'add', // 创建文件
        path: 'src/components/{{name}}/index.tsx',  // 生成的文件
        templateFile: 'templates/index.tsx',  // 模板文件
      },
      {
        type: 'add',
        path: 'src/components/{{name}}/index.less',
        templateFile: 'templates/index.less',
      },
      {
        type: 'add',
        path: 'src/stories/{{name}}.stories.tsx',
        templateFile: 'templates/index.stories.tsx',
      },
    ],
  });
};

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:13:49  更:2022-07-17 16:14:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/11 11:37:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码