Để bắt đầu, các bạn cần chuẩn bị một số công cụ cần thiết. Tôi cũng đã chuẩn bị đường link đến tài liệu cài đặt nếu như bạn chưa biết về các công cụ này

#1 Cài đặt storybook 🛠️

Dùng create-react-app tạo React.js project, nhớ bổ sung thêm option sử dụng template typescript

$ yarn create react-app my-first-react-component --template typescript

Cài đặt storybook bên trong dự án. Nhớ là bên trong dự án chứ ko phải bên ngoài

$ cd my-first-react-component
$ npx sb init

Sau khi cài đặt xong, chạy storybook

$ yarn storybook

#2 Xóa các file không cần thiết 🛑

Chúng ta sẽ chỉ giữ lại thư mục src/stories và xóa các thư mục còn lại

Thư mục và file cần xóa
Thư mục và file cần xóa (Xem ảnh gốc)

Đổi tên thư mục src/stories thành src/components - không bắt buộc, mục đích của việc này là do cá nhân tôi thích tên thư mục rõ ràng với chức năng

Đổi tên thành /components
Đổi tên thành /components (Xem ảnh gốc)

Đừng quên mở lại storybook xem có bât kì sai xót nào không yarn storybook. Nếu không có vấn đề gì, ta sẽ cần tạo thêm src/index.ts. Mục đích là để có thể import được module

// src/index.ts

import { Button } from "./components/Button";

export { Button };

#3 Bổ sung cài đặt cho tsconfig.json vs package.json 📺

Tiếp theo, cần phải bổ sung 1 số cài đặt cho typescript là outDir, declaration, declarationDirexclude

// tsconfig.json

{
  "compilerOptions": {
    ...
    "outDir": "lib", // => chỉ rõ thư mục output sau khi build
    "declaration": true, // => yêu cầu typescript tạo ra file .d.ts
    "declarationDir": "lib", // => thư mục lưu file .d.ts
    ...
  },
  ...
  "exclude": ["node_modules", "lib"] // loại trừ các thư mục không cần thiết
}

Mở file package.json và bổ sung các option sau để

  • private: cho phép public module
  • main: chỉ rõ file chính
  • module: chỉ rõ file module
  • types: chỉ rõ file định nghĩa kiểu dữ liệu
// package.json

{
  ...
  "private": false,  // => xóa đi hoặc chuyển giá trị sang false
  "main": "lib/index.js",  
  "module": "lib/index.esm.js",
  "types": "lib/index.d.ts",
  ...
}

#4 Cài đặt rollup 🗳️

Trước khi cài đặt,

$ yarn add --dev rollup rollup-plugin-typescript2 @rollup/plugin-commonjs @rollup/plugin-node-resolve rollup-plugin-peer-deps-external rollup-plugin-postcss postcss

Tạo file rollup.config.js với nội dung sau

// rollup.config.js

import peerDepsExternal from "rollup-plugin-peer-deps-external";
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "rollup-plugin-typescript2";
import postcss from "rollup-plugin-postcss";

const packageJson = require("./package.json");

export default {
  input: "src/index.ts",
  output: [
    {
      file: packageJson.main,
      format: "cjs",
      sourcemap: true,
    },
    {
      file: packageJson.module,
      format: "esm",
      sourcemap: true,
    },
  ],
  plugins: [
    peerDepsExternal(),
    resolve(),
    commonjs(),
    typescript({ useTsconfigDeclarationDir: true }),
    postcss({
      extensions: [".css"],
    }),
  ],
};

Cập nhật file package.json và bổ sung lệnh build

// package.json
{
  ...
  "scripts": {
    ...
    "build": "rollup -c",
  },
}

Chạy thử lệnh build và xem kết quả

$ yarn build

// -----------------------------------------
yarn run v1.22.11
warning package.json: No license field
$ rollup -c

src/index.ts → lib/index.js, lib/index.esm.js...
created lib/index.js, lib/index.esm.js in 2.7s
Done in 3.57s.

#5 Đăng nhập npm và publish sản phẩm 🚩

Mở terminal và sử dụng tài khoản npm để đăng nhập. Nếu bạn không có tài khoản npm thì có thể đăng ký tại đây

$ npm login
Username: watiss09
Password:
Email: (this IS public) watiss09@gmail.com
Logged in as watiss09 on https://registry.npmjs.org/.

Bước cuối cùng, chạy lệnh sau, nếu không có lỗi gì thì xin chúc mừng, bạn đã thành công

$ npm publish

Còn nếu gặp phải lỗi sau, thì khả năng cao là do tên module của bạn đã tồn tại, đơn giản là vào package.json và thay đổi trường name và thực hiện publish lại

Lỗi do trùng tên module
Lỗi do trùng tên module (Xem ảnh gốc)

Kết luận

Với 5 bước trên hi vọng các bạn đã có thể tự publish được module của chính mình lên npm. Cám ơn các bạn đã giành thời gian cho bài viết này và hẹn gặp lại