Tool library packaging process

This chapter is mainly about package, package the component library, use gulp to control the package process, and use rollup to package (because the operation process is complicated, some steps will be omitted, not too detailed, but it will be clear, there will be annotations in the code, you can see the official document for relevant content).

PNPM install gulp @types/gulp sucrase -w -d

Json: gulp -f build/gulpfile.ts: gulpfile.ts: gulpfile.ts

Add the build directory to the root directory. The structure is as follows: paths.ts holds the defined public path, and index.ts holds some public methods

The code for gulpfile.ts is as follows:

// Package mode: series parallel
import { series, parallel } from "gulp";
import { withTaskName,run } from "./utils"

// Gulp is not called package, do code conversion vite

/** * 1. Package style * 2. Package tool method * 3. Package all components * 4. Package each component * 5. Generate a component library * 6. Publish components */
export default series(
  withTaskName("clean".async () => run('rm -rf ./dist')),  // Delete the dist directory
);

Copy the code

The withTaskName method is encapsulated in utils/index.ts.

/** * child process * child_process.spawn(command[, args][, options]) * command 
      
        Command to run. * args 
       
         List of string arguments. * the options < Object > * - CWD < string > | < URL > the child to the current working directory of the * - the stdio < Array > | < string > child process standard input/output configuration. 'inherit', via the corresponding standard input and output streams into/out the parent * - shell < Boolean > | < string > if it is true, then run the command in the shell. Use '/bin/sh' on Unix and process.env.ComSpec on Windows. Different shells can be specified as strings. See shell requirements and the default Windows shell. Default: false (no shell) x */
       []>
      
import { spawn } from "child_process";
import { projectRoot } from "./paths";

// Define the name of each task
export const withTaskName = <T>(name: string, fn: T) = >
  Object.assign(fn, { displayName: name });


// Start a child process in Node to run the script
export const run = async (command: string) = > {return new Promise((resolve) = > {
    / / split command For example: rm - rf is divided into [' rm ', '- rf], decompose/CMD, args...
    const [cmd, ...args] = command.split("");
    const app = spawn(cmd, args, {
        cwd:projectRoot,
        stdio:"inherit".shell:true  // Git bash is only supported on Linux by default
    });
    The 'close' event is emitted after the process has terminated and the child's standard input/output stream has been closed
    app.on('close',resolve)  // 
  });
};

Copy the code

Create a dist directory in the root directory and run NPM run build to see if it is deleted. Select git bash under VScode or rm is not a command in Windows

See after executiondistThe directory has been successfully deleted

What we are going to do is put three packages under packagescomponents.theme-chalk.utilsPackage them separately and finally generate them in the root directorydistDirectory, so we’re going to go under each directorypackage.jsonNext, addbuildScript, executebuildWhen scripting, it will look in the current directorygulpThe configuration filegulpfile.ts

Add gulp configuration file gulpfile.ts under theme-chalk first

gulp-sass@types/gulp-sass@types /sass gulp-autoprefixer @types/gulp-autoprefixer @types/gulp-clean-css gulp-clean-css -w -DCopy the code
PNPM install gulp-sass@types/gulp-sass @types/sass gulp-autoprefixer @types/gulp-autoprefixer @types/gulp-clean-css gulp-clean-css-w -d * gulp-autoprefixer: adds the style prefix gulp-clean-css: compresses the CSS */
import gulpSass from "gulp-sass";
import dartSass from "sass";
import autoprefixer from "gulp-autoprefixer";
import cleanCss from "gulp-clean-css";
import path from "path";

/** * gulp is executed in the same way as a pipe, starting from the inlet to the outlet and executing the */ step by step
import { series, src, dest } from "gulp";

/** * Sass file */
function compile() {
  const sass = gulpSass(dartSass);
  // Start from SCSS file under SRC => compile to CSS => add prefix => compress => finally output to CSS directory under current directory dist
  return src(path.resolve(__dirname, "./src/*.scss"))
    .pipe(sass.sync())
    .pipe(autoprefixer())
    .pipe(cleanCss())
    .pipe(dest("./dist/css"));
}

/** * handle font files */
function copyfont() {
    // Start with all files under the SRC fonts folder => compress => finally output to the font directory under the current directory dist
    return src(path.resolve(__dirname,'./src/fonts/**')).pipe(cleanCss()).pipe(dest("./dist/fonts"))}/** * outputs the packed CSS to the root dist */
function copyfullstyle(){
    const rootDistPath = path.resolve(__dirname,'.. /.. /dist/theme-chalk')
    return src(path.resolve(__dirname,'./dist/**')).pipe(dest(rootDistPath))
}

export default series(compile, copyfont,copyfullstyle);

Copy the code

Dist from the root directory, change the name to theme-chalk. Now let’s test this by executing NPM run build under theme-chalk. Compile, copyFONT, copyfullStyle, the result is as follows:

The generated directory is as follows:

Now that the style files are handled, let’s handle utils, add gulp configuration file gulpfile.ts under utils, and install a dependency on gulp-typescript to handle ts files

import { buildPackages } from ".. /.. /build/packages"


export default buildPackages(__dirname,'utils')
Copy the code
PNPM install gulp-typescript -w-dCopy the code

Since we’ll be dealing with TS more than once, encapsulate a method to create a new file called packes.ts in the build directory

Then define the packaged output directory under Build /utils/ Paths

And then we’re going to taketsSeparately packaged ascjsandesmTwo module specifications, so we first define a configuration file inbuild/utilsNew fileconfig.ts, the code is as follows:

import path from "path";
import { outDir } from "./paths";
export const buildConfig = {
  esm: {
    module: "ESNext".// tsconfig output result of es6 module
    format: "esm".// The formatted module specification needs to be configured
    output: {
      name: "es".// Package to the directory in the dist directory
      path: path.resolve(outDir, "es"),},bundle: {
      path: "z-plus/es",}},cjs: {
    module: "CommonJS".format: "cjs".output: {
      name: "lib".path: path.resolve(outDir, "lib"),},bundle: {
      path: "z-plus/lib",}}};export type BuildConfig = typeof buildConfig;
Copy the code

This is finally handled in the packes.ts just defined

// specifically package util, instruction, hook
import { series, parallel, src, dest } from "gulp";
import { buildConfig } from "./utils/config";
import path from "path";
import { outDir, projectRoot } from "./utils/paths";
import ts from "gulp-typescript";
import { withTaskName } from "./utils";

// Package
export const buildPackages = (dirname: string, name: string) = > {
  const tasks = Object.entries(buildConfig).map(([module, config]) = > {
    const output = path.resolve(dirname, config.output.name);
    // Install dependencies on gulp-typescript
    return series(
      // Process the ts file
      withTaskName(`build${dirname}`.() = > {
        const tsConfig = path.resolve(projectRoot, "tsconfig.json"); // ts configuration file path
        const inputs = ["**/*.ts".! "" gulpfile.ts".! "" node_modules"];
        return src(inputs)
          .pipe(
            ts.createProject(tsConfig, {
              declaration: true.// The declaration file needs to be generated
              strict: false.// Turn off strict mode
              module: config.module,
            })()
          )
          .pipe(dest(output));
      }),
      withTaskName(`copy:${dirname}`.() = > {
          // Place the packaged files in es=>utils and lib =>utils
          // Copy the utils module to the es and lib directories in the dist directory
          return src(`${output}/ * * `).pipe(dest(path.resolve(outDir,config.output.name,name)))
      })
    );
  });

  returnparallel(... tasks); };Copy the code

NPM run build (utils)

You can see in theutilsThere are two directoriesesandlibAnd,copyTo the root directorydistIn the directory, the directory is as follows:

Now theme-chalk and utils have been handled, but we need to execute the build script in each directory separately, which is too troublesome. I want to execute the build in the root directory, pack them separately, and output the result to the dist directory in my root directory. So add a task to gulpfile.ts in the root directory and ask it to execute each build for me separately

In build/gulpfile.ts: add

. withTaskName("buildPackages".() = > run("pnpm run --filter ./packages --parallel build"))...Copy the code

Then we delete the root directorydist, run in the root directorynpm run build, test it:

You can see that the build scripts in each directory are executed for us, and the final output to the root directory dist:

At this point, our theme-chalk and utils packaging is complete, and we can then handle the packaging of the components


The rest of the code can be viewed at Gitee