preface

We already know the dev and Dist builds of Air-UI in the home-built VUE component AIR-UI (14) — Packaged Builds (Dev and Dist). Let’s take a look at why a PUB build task is needed and what it is used for.

Use the master branch directly as a branch of the third-party cull

Suppose we don’t have a PUB task. Generate the lib directory directly using the Dist build, and then commit the code to the Master branch with a master tag. At this point, we can load air-UI in this way on a project:

"air-ui": "Git+ssh://[email protected]: web/vue - UI. Git # v0.0.4".Copy the code

And then we quote very smoothly:

import AirUI from 'air-ui';
import 'air-ui/lib/styles/index.css';

Vue.use(AirUI);
Copy the code

An error was reported when compiling:

ERROR in./node_modules/air-ui/lib/styles/index.css (./node_modules/css-loader/dist/cjs.js?? ref-2 -- 1! ./node_modules/postcss-loader/src! ./node_modules/air-ui/lib/styles/index.css) Module build failed (from ./node_modules/postcss-loader/src/index.js):
Error: Loading PostCSS Plugin failed: Cannot find module 'postcss-import'
Copy the code

It was found in the air-UI directory.postcssr.js, because vue will handle postCSS if it finds this file at compile time. When I delete the.postcsrc. Js file from the air-UI directory, it works fine. This means that when air-UI is loaded as a third-party library, you don’t need a lot of messy files, just a lib directory, and nothing else.

So here comes another issue: the directory structure of the project’s development environment is different from the directory structure downloaded as a third-party package. In the case of Element-UI, the master branch of his project looks like this:

There are still a lot of files, but if downloaded as a third-party library, this is all that’s left:

So these two are definitely not the same branch. Because files are different. So air-UI is going to do the same thing, removing the ones that are not used, or are only available in the Dev environment, and keeping only the core files for third-party libraries.

The master – release branch

The current air-UI dependencies, when downloaded, are all files in the master branch, which is actually not right. You don’t need so many files, just lib and package.json and readme.

The easiest way to do this is to create another branch, the master-release branch, and put the packaged lib directory, package.json, and readme files into this branch, and then tag from this branch. And then if you pull this tag that’s what this branch is.

That’s all that’s left of the master-release branch. All other unnecessary files were cut out. Then tag from that branch and make a new version. Then update the new version again in the host project:

The downloaded file is the right one. Keep only the files that need to be referenced, and discard all other files that are not needed. And there was no problem compiling.

Use a script

One of the problems is that every time I want to update the version, I have to bundle yarn Dist in the Master branch, copy the lib directory to the master-release branch, and tag the master-release branch. It can get messy. So the solution is to turn this process into a task, and then turn the Git operation into a shell script. Just like element-UI, shell scripts can be used to do this, such as yarn pub, which contains the following operations:

  1. Check whether the current branch is remotemasterBranch, if not, returns an error
  2. performyarn distGenerate the lib directory
  3. Save the lib directory to a git ignore directorylib_tmp
  4. commit and push masterBranch (if status changes)
  5. Switch to themaster-releaseBranch,lib_tmpOverwrite the lib directory
  6. commit and push master-releasebranch
  7. master-releasePlay tag
  8. Transfer temporary fileslib_tmpdelete

So we’ll create a new file called build/git-release.sh to handle some git operations (assuming the master and master-release branches already exist):

#! /usr/bin/env sh echo "start publish version: "$1 if test "$(git rev-parse --abbrev-ref HEAD)" == "master"; then echo "current branch is master" echo "start commit and push master" git add -A git commit -m "[master build] "$1 git push origin echo "push success" echo "copy master lib to lib_tmp" mkdir lib_tmp cp -rf lib/* lib_tmp echo "check branch master-release" git checkout master-release echo "copy lib_tmp to master-release lib" cp -rf lib_tmp/* lib echo "start commit and push master-release" git add -A git commit -m "[master-release build] "$1 git push origin echo "push master-release success" echo "create tag...." git tag -a $1 -m "version "$1 git push origin $1 echo "push tag success" echo "remove lib_tmp" rm -rf lib_tmp else echo "current branch is not master" exit 128; fiCopy the code

The command to execute is YARN pub: (because my development environment is Windows, so execute the.sh file, do not add sh command)

"pub": "npm run dist && build/git-release.sh v0.0.20".Copy the code

Execute the following log:

Start publish version: v0.0.20 current branch is master start commit and push master Warning: LF will be replaced by CRLF in lib/air-ui.common.js. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in package.json. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in src/components/index.js. The file will have its original line endings in your working Directory. [master e6d5770] [master build] v0.0.20 3 files changed, 4 insertions(+), 4 deletions(-) 8, done. Delta compression using up to 4 threads. Compressing objects: 100% (8/8), done. Writing objects: 100% (8/8), 703 bytes | 703.00 KiB/s, done. Total 8 (7) delta, reused 0 (delta 0) To gitlab.xxx.com:web/air-ui.git 9690368.. e6d5770 master -> master push success copy master lib to lib_tmp check branch master-release Checking out files: 100% (929/929), done. Switched to branch 'master-release' Your branch is up to date with 'origin/master-release'. copy lib_tmp to master-release lib start commit and push master-release warning: Air-crlf will be replaced by air-crlf in lib/ air-ui.mon.js.... The file will have its original line endings in your working directory. [master-release f576e93] [master-release build] V0.0.20 1 file changed, 1 insertion(+), 1 deletion(-) Counting objects: 4, done. Delta compression using up to 4 threads. Compressing objects: 100% (4/4), done. Writing objects: 412.00 100% (4/4), 412 bytes | KiB/s, done. Total 4 (3) delta, reused zero (0) delta remote: remote: To create a merge request for master-release, visit: remote: http://gitlab.xxx.com/web/air-ui/merge_requests/new?merge_request%5Bsource_branch%5D=master-release remote: To gitlab.xxx.com:web/air-ui.git ce49143.. f576e93 master-release -> master-release push master-release success create tag.... Counting objects: 1, done. Writing objects: 100% (1/1), 160 bytes | 160.00 KiB/s, done. Total 1 (delta 0), In flue 0 (delta 0) To gitlab.xxx.com:web/air-ui.git * [new tag] v0.0.20 -> v0.0.20 push tag success remove lib_tmpCopy the code

From the commit log, it is true that both branches are pushed and tagged:

Note that lib_tmp is a temporary directory for lib and will eventually be deleted, but it is best to set it to git’s.ignore file in the master and master-release branches. Another drawback is that every time I run YARN pub, I have to manually change the version number after the git-relex. sh command. Also, the version number in components/index.js should be changed manually, which is not smart enough.

There was a problem cutting back to the master branch

And there’s also a problem with doing something like that, where you end up switching to the Master-release branch, manually switching to the Master branch every time. It’s also a hassle. Git-relege. sh = master;

. rm -rf lib_tmp echo"check back branch master"
 git checkout master
...
Copy the code

But it turned out to be an error:

. push tag success remove lib_tmp check back branch master error: cannot stat'build/git-release.sh': Permission denied
Copy the code

The build/git-release.sh file was not available when the master-release branch was switched. So if we want to cut back, we should make sure that build/git-release.sh is still there when we cut to the master-release branch. That will do.

Optimize – make it interactive

Because each time the pub task is executed, the version number is manually changed in the pub directive and components/index.js. This one is a hassle. So we need to optimize the implementation of gulp, including the execution of shell files, to do the following:

  1. To start with an interactive interface, you need to enter the version number and verify the rules:
  2. replacecomponents/index.jsThe version number below
  3. playdist
  4. Execute shell script (execute with node with arguments)
  5. Finally switch tomasterbranch

The specific gulp code is as follows:

//============= pub build start ===========
var seq = require("gulp-sequence");
var replace = require("gulp-replace");
var rename = require('gulp-rename');
var del = require('del');
var prompt = require('gulp-prompt');
const childProcess = require('child_process');


var tagVersion = ' ';
// Enter the version number
gulp.task('pubVersion', cb => {
  return gulp.src('./src/components/index.js')
    .pipe(prompt.prompt({
      type: 'input'.name: 'version'.message: 'Input your tag version (like v0.0.x)? '.validate: function(version){
        // Regex validation is required
        return /^v\d+.\d+.\d+$/.test(version); }},function(res){
      console.log("version:" + res.version);
      tagVersion = res.version;
    }))
    .pipe(replace(/version:(.+),/g.function(match, p1, p2){
        return `version: '${tagVersion}', `
    }))
    .pipe(gulp.dest('./src/components'));
});
// Dist
gulp.task('pubDist'.function (cb) {
  var workerProcess = childProcess.exec('npm run dist', {
    cwd: '/'
  }, cb);
  workerProcess.stdout.on('data'.function (data) {
    console.log(data);
  });
  workerProcess.stderr.on('data'.function (data) {
    console.log('stderr: ' + data);
  });
});
// Copy build/git-release.sh to the root directory and rename it.
gulp.task('pubCopyShell'.function() {
  return gulp.src('./build/git-release.sh')
    .pipe(rename('git-release-tmp.sh'))
    .pipe(gulp.dest('/'));
});
// Then execute the shell directive
gulp.task('pubDoShell'.function (cb) {
  var workerProcess = childProcess.exec(`git-release-tmp.sh ${tagVersion}`, {
    cwd: '/'
  }, cb);
  workerProcess.stdout.on('data'.function (data) {
    console.log(data);
  });
  workerProcess.stderr.on('data'.function (data) {
    console.log('stderr: ' + data);
  });
});
// Finally delete the temporary shell file
gulp.task('pubDelTempShell', cb => {
  return del([
    './git-release-tmp.sh'
  ], cb);
});

gulp.task('pub', seq('pubVersion'.'pubDist'.'pubCopyShell'.'pubDoShell'.'pubDelTempShell'));
//============= pub build end ===========
Copy the code

You can see that because what I’m going to do is execute a temporary sh file: git-release-tmp.sh. So we can go back to the master branch.

And this is interactive mode, allows us to enter the rule of V.X.X.X version number, the specific log is as follows:

F:\code\air-ui>gulp pub
[15:55:57] Using gulpfile F:\code\air-ui\gulpfile.js
[15:55:57] Starting 'pub'. [15:55:57] Starting 'pubVersion'. ? input your tag version (like v0. 0.x)? v0. 027.
version:v0. 027.
[15:56:02] Finished 'pubVersion' after 4.6 s
[15:56:02] Starting 'pubDist'. > air-ui@1.0. 0 dist F:\code\air-ui
> npm run clean && webpack --config build/webpack.common.js && webpack --config build/webpack.component.js && npm run css && npm run lang && npm run theme


> air-ui@1.0. 0 clean F:\code\air-ui
> rimraf lib && rimraf test/ * * /coverage


Hash: c3c11a0506830b38e6f8
Version: webpack 3.12. 0
Time: 12278ms
           Asset     Size  Chunks                    Chunk Names
air-ui.common.js  1.29 MB       0  [emitted]  [big]  app
   [1] ./src/utils/util.js 7.4 kB {0} [built]
 ...
    + 468 hidden modules


> air-ui@1.0. 0 css F:\code\air-ui
> gulp buildCss

Using gulpfile F:\code\air-ui\gulpfile.js

[15:56:34]
Starting 'compile'. [15:56:34]
Starting 'copyfont'. [15:56:34]
Finished 'copyfont' after 315 ms

[15:56:41] Finished 'compile' after 7.06 s

[15:56:41] Starting 'buildCss'. [15:56:41] Finished 'buildCss' after 40Mu s > air - UI @1.0. 0 lang F:\code\air-ui
> gulp copylang

[15:56:44]
Using gulpfile F:\code\air-ui\gulpfile.js

[15:56:44]
Starting 'copylang'. [15:56:44]
Finished 'copylang' after 279 ms


> air-ui@1.0. 0 theme F:\code\air-ui
> gulp theme

[15:56:46]
Using gulpfile F:\code\air-ui\gulpfile.js

[15:56:46]
Starting 'theme'. [15:56:46]
Starting 'del-old-theme'. [15:56:47]
Finished 'del-old-theme' after 37 ms
[15:56:47] Starting 'biz-theme'. [15:56:47] Starting 'biz-theme-copy'. [15:56:47]
Finished 'biz-theme-copy' after 576 ms
[15:56:47] Starting 'biz-theme-replace'. [15:56:47]
Finished 'biz-theme-replace' after 16 ms
[15:56:47] Starting 'biz-theme-compile'. [15:56:59]
Finished 'biz-theme-compile' after 12 s
[15:56:59] Starting 'biz-theme-font'. [15:56:59]
Finished 'biz-theme-font' after 12 ms

[15:56:59] Finished 'biz-theme' after 12 s
[15:56:59] Starting 'personal-theme'. [15:56:59] Starting 'personal-theme-copy'. [15:56:59]
Finished 'personal-theme-copy' after 481 ms
[15:56:59] Starting 'personal-theme-replace'. [15:56:59]
Finished 'personal-theme-replace' after 8 ms
[15:56:59] Starting 'personal-theme-compile'. [15:57:08] Finished 'personal-theme-compile' after 8.54 s
[15:57:08] Starting 'personal-theme-font'. [15:57:08]
Finished 'personal-theme-font' after 12 ms
[15:57:08] Finished 'personal-theme' after 9.04 s
[15:57:08] Starting 'del-theme-tmp'. [15:57:08] Finished 'del-theme-tmp' after 129 ms
[15:57:08] Finished 'theme' after 21 s

[15:57:08] Finished 'pubDist' after 1.1 min
[15:57:08] Starting 'pubCopyShell'. [15:57:08] Finished 'pubCopyShell' after 9.44 ms
[15:57:08] Starting 'pubDoShell'. [15:57:44] Finished 'pubDoShell' after 36 s
[15:57:44] Starting 'pubDelTempShell'. [15:57:44] Finished 'pubDelTempShell' after 16 ms
[15:57:44] Finished 'pub' after 1.78 min
Copy the code

That’s perfect. The instruction changed to:

"pub": "gulp pub".Copy the code

Optimize – change the version number of package.json

The version of package.json has not been changed.

It’s still 1.0.0 all the time, and it still needs to be fixed. The package.json file of the branch should also be replaced when the masterrelease is switched, so that the package.json file of the two branches will be the same:

So gulP also adds these two tasks:

gulp.task('pubPackageVersion', cb => {
  return gulp.src('./package.json')
    .pipe(replace(/"version":(.+),/g.function(match, p1, p2){
      return `"version": "${tagVersion.substring(1,tagVersion.length)}", `
    }))
    .pipe(gulp.dest('/'));
});
// Copy package.json to a temporary file
gulp.task('pubCopyPackage'.function() {
  return gulp.src('./package.json')
    .pipe(rename('package-tmp.json'))
    .pipe(gulp.dest('/'));
});
Copy the code

Git-release. sh is also required to override package.json:

echo "copy package-tmp.json to master-release package.json"
cp -rf package-tmp.json package.json
Copy the code

The.ignore file also ignores package-tmp.json. (Master and master-release are set). Then do one last thing, and see what it looks like. Look at the commit record:

If you look at the commit record for the master, the version has changed in all three places:

The version of the master-release has been changed in both places:

And you’re done. The complete code for the gulp task is as follows:

var seq = require("gulp-sequence");
var replace = require("gulp-replace");
var rename = require('gulp-rename');
var del = require('del');
var prompt = require('gulp-prompt');
const childProcess = require('child_process');

/** Whether OS is Windows */
const isWin = /^win/.test(process.platform);

//============= pub build start ===========
var tagVersion = ' ';
// Enter the version number
gulp.task('pubVersion', cb => {
  return gulp.src('./src/components/index.js')
    .pipe(prompt.prompt({
      type: 'input'.name: 'version'.message: 'Input your tag version (like v0.0.x)? '.validate: function (version) {
        // Regex validation is required
        return /^v\d+.\d+.\d+$/.test(version); }},function (res) {
      console.log("version:" + res.version);
      tagVersion = res.version;
    }))
    .pipe(replace(/version:(.+),/g.function (match, p1, p2) {
      return `version: '${tagVersion.substring(1, tagVersion.length)}', `
    }))
    .pipe(gulp.dest('./src/components'));
});
// Dist
gulp.task('pubDist'.function (cb) {
  var workerProcess = childProcess.exec('npm run dist', {
    cwd: '/'
  }, cb);

  workerProcess.stdout.on('data'.function (data) {
    console.log(data);
  });

  workerProcess.stderr.on('data'.function (data) {
    console.log('stderr: ' + data);
  });
});
// Change the package with the version in package.json:
gulp.task('pubPackageVersion', cb => {
  return gulp.src('./package.json')
    .pipe(replace(/"version":(.+),/g.function (match, p1, p2) {
      return `"version": "${tagVersion.substring(1, tagVersion.length)}", `
    }))
    .pipe(gulp.dest('/'));
});
// Copy package.json to a temporary file
gulp.task('pubCopyPackage'.function () {
  return gulp.src('./package.json')
    .pipe(rename('package-tmp.json'))
    .pipe(gulp.dest('/'));
});

// Copy build/git-release.sh to the root directory and rename it.
gulp.task('pubCopyShell'.function () {
  return gulp.src('./build/git-release.sh')
    .pipe(rename('git-release-tmp.sh'))
    .pipe(gulp.dest('/'));
});
// Then execute the shell directive
gulp.task('pubDoShell'.function (cb) {
  var workerProcess = childProcess.exec(`${isWin ? ' ' : 'sh'} git-release-tmp.sh ${tagVersion}`, {
    cwd: '/'
  }, cb);

  workerProcess.stdout.on('data'.function (data) {
    console.log(data);
  });

  workerProcess.stderr.on('data'.function (data) {
    console.log('stderr: ' + data);
  });
});
// Delete the temporary file
gulp.task('pubDelTemp', cb => {
  return del([
    './git-release-tmp.sh'.'./package-tmp.json'
  ], cb);
});

gulp.task('pub', seq(
  'pubVersion'.'pubDist'.'pubPackageVersion'.'pubCopyPackage'.'pubCopyShell'.'pubDoShell'.'pubDelTemp'
));

//============= pub build end ===========
Copy the code

Git-release.sh:

#! /usr/bin/env sh echo "start publish version: "$1 if test "$(git rev-parse --abbrev-ref HEAD)" == "master"; then echo "current branch is master" echo "start commit and push master" git add -A git commit -m "[master build] "$1 git push origin echo "push success" echo "copy master lib to lib_tmp" mkdir lib_tmp cp -rf lib/* lib_tmp echo "check branch master-release" git checkout master-release echo "copy lib_tmp to master-release lib" cp -rf lib_tmp/* lib echo "copy package-tmp.json to master-release package.json" cp -rf package-tmp.json package.json echo "start commit and push master-release" git add -A git commit -m "[master-release build] "$1 git push origin echo "push master-release success" echo "create tag...." git tag -a $1 -m "version "$1 git push origin $1 echo "push tag success" echo "remove lib_tmp" rm -rf lib_tmp echo "check back branch master" git checkout master else echo "current branch is not master" exit 128; fiCopy the code

The instructions are:

"pub": "gulp pub".Copy the code

conclusion

With the PUB task, we implemented the following:

  1. When packaging, enter the tag version number and change it at the same timemasterBranch of the pre-packcomponents/index.jspackage.jsonThe files, packed upair-ui.common.jsAnd submit it to the online library
  2. And the lib directory andpackage.jsonFile synchronization tomaster-releasebranch
  3. master-releaseCommit to the online library and tag it
  4. So let’s go back to the originalmasterbranch

The Element-UI pub task is similar, but it is more complex and takes more into account. Air-ui requires less consideration and is correspondingly more understandable.

In the next section, we’ll take a look at some of the weirdest things we’ve encountered while building air-UI components and how to get around them.


Series of articles:

  • Air-ui (1) — Why do I need to build an Element UI component
  • Self-built VUE component AIR-UI (2) — Take a look at the Element UI project
  • Self-built VUE component AIR-UI (3) – CSS development specification
  • Air-ui (4) — Air-UI environment setup and directory structure
  • Air-ui (5) — Create the first vUE component, Button
  • Self-built VUE component AIR-UI (6) – Creates built-in service components
  • Build vUE component AIR-UI (7) – Create command component
  • Self-built VUE component AIR-UI (8) — Implementation part introduces components
  • Build your own VUE component air-UI (9) — document with Vuepress
  • Air-ui (10) — Vuepress Documentation (Advanced version)
  • Vue Component Air-UI (11) — Vuepress Documentation (Crawl version)
  • Self-built VUE component AIR-UI (12) — Internationalization mechanism
  • Self-built VUE Component AIR-UI (13) — Internationalization Mechanism (Advanced Version)
  • Self-built VUE component AIR-UI (14) — Packaged Build (Dev and Dist)
  • Self-built VUE component AIR-UI (15) — Theme customization
  • Self-built VUE component AIR-UI (16) – Packages to build pub tasks
  • Build your own VUE component AIR-UI (17) – Develop a pit crawl and summary