gulp使用入门&在angular项目中自动更新打包时间

背景

做项目的时候,不知大家是否会遇到如下场景:后端或者测试人员经常询问是否重新部署过前端页面;重新部署过后无法确定用户是否在使用最新页面,只得让他们多刷新几次;许久未维护的项目不清楚上次的部署时间。 为解决以上问题,我们可以将打包时间作为版本号并显示在页面上,让每个使用者清晰知道当前项目的打包时间。

思路

  1. 定义一个变量用于存储打包时间;
  2. 前端页面读取并显示这个变量的值;
  3. 每次打包时,使用当前时间覆写该变量的值;

第1,2点很好实现。第3点我们使用gulp实现。gulp是基于nodejs的自动化构建工具,可以使用它在项目开发过程中自动执行任务。我们只需在执行打包脚本前,先执行覆写打包变量的脚本即可

实现

  1. 运行node -v,确定已安装nodejs环境;

  2. 全局安装gulp,这边以npm安装为例。

    bash 复制代码
    # 全局安装gulp
    npm install -g gulp-cli
    # 检查是否安装成功
    gulp --verison
  3. 在项目中安装gulp相关依赖:npm install gulp gulp-clean ts-node date-fns fs-extra chalk --save-dev

    gulp gulp-clean为gulp依赖;ts-node让我们可以在nodejs下直接运行typescript文件;date-fns是一个日期处理库,此处用于格式化当前时间;fs-extrafs包的功能补充包;chalk用于在命令行中使用指定颜色显示文字信息。如果想了解更多信息,请至npmjs.com下自行查阅相关资料。

  4. 在项目根目录下新建配置文件gulpfile.js,文件内容如下:

    js 复制代码
    const path = require('path');
    
    const projectDir = __dirname;
    const tsconfigPath = path.join(projectDir, 'scripts/gulp/tsconfig.json');
    
    if (projectDir.includes(' ')) {
      console.error('Error: Cannot run the build tasks if the project is ' +
        'located in a directory with spaces in between. Please rename your project directory.');
      process.exit(1);
    }
    
    console.log('compiling...');
    
    
    require('ts-node').register({
      project: tsconfigPath
    })
    // 引入typescript编写的文件
    require('./scripts/gulp/gulpfile');
  5. 新建scripts/gulp/gulpfile.ts,内容如下:

    typescript 复制代码
    import { task, series } from 'gulp';
    import './tasks/index';
    import { format } from 'date-fns';
    import * as fs from 'fs-extra';
    import * as path from 'path';
    import * as chalk from 'chalk';
    
    const appVersionPath = 'src/app';
    task('set-app-version', (done) => {
      const version = `Ver ${format(new Date(Date.now()), 'YY.MM.DD.HHmm')}`;
      // eslint-disable-next-line no-console
      console.log(chalk.yellow(`当前版本号:${version}`));
      fs.writeFileSync(path.join(appVersionPath, 'app-version.ts'), `export const APP_VERSION = '${version}';`);
      done();
    });
    
    task('init-site', execNodeTask('@angular/cli', 'ng', ['build', '--prod']));
    
    task('build:site', series('set-app-version', 'init-site'));

    在同级目录位置下新建tsconfig.json,内容如下:

    json 复制代码
    {
      "compilerOptions": {
        "experimentalDecorators": true,
        "noUnusedParameters": true,
        "noUnusedLocals": true,
        "lib": ["es2015", "dom"],
        "module": "commonjs",
        "moduleResolution": "node",
        "outDir": "../../dist",
        "strictNullChecks": true,
        "strictFunctionTypes": true,
        "noImplicitThis": true,
        "noEmitOnError": true,
        "noImplicitAny": true,
        "target": "es5",
        "types": ["node"],
        "baseUrl": "."
      },
      "files": ["gulpfile.ts"]
    }

    如上所示我们在gulpfile.ts下新建了build:site任务,里面包含两个子任务:set-app-versioninit-site,分别对应设置程序版本号(此处使用打包时间为程序版本号,格式为:Ver 23.08.12.2145)和angular打包任务。

    • set-app-version(设置版本号):将当前日期信息作为版本作为版本信息写入src/app/app-version.ts文件,最终app-version.ts文件内容如下:

      typescript 复制代码
      export const APP_VERSION = 'Ver 23.08.13.1354';

      最终页面组件只需导入APP_VERSION变量并显示在合适位置即可。

    • init-site,使用execNodeTask方法调用对应框架(此处调用angular框架的ng build命令)的打包方法即可。execNodeTask函数实现如下:

      typescript 复制代码
      import * as child_process from 'child_process';
      import * as gulp from 'gulp';
      import * as os from 'os';
      
      /**
       * 运行指定的npm包命令
       * @param packageName npm包名
       * @param executable 可执行命令
       * @param args 参数
       * @param env 环境变量
       */
      export function execNodeTask(packageName: string, executable: string | string[], args?: string[], env: any = {}): gulp.TaskFunction {
        if (!args) {
          // tslint:disable-next-line:no-parameter-reassignment
          args = executable as string[];
          // tslint:disable-next-line:no-parameter-reassignment
          executable = '';
        }
      
        // tslint:disable-next-line:no-any
        return (done: (err: any) => void) => {
          // tslint:disable-next-line:no-any
          resolveBin(packageName, { executable: executable }, (err: any, binPath: string) => {
            if (err) {
              done(err);
            } else {
              // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
              execTask('node', ['--max_old_space_size=8000', binPath].concat(args!), env)(done);
            }
          });
        };
      }
      
      export function execTask(binPath: string, args: string[], env: any = {}): any {
        return (done: (err?: string) => void) => {
          // https://github.com/angular/angular-cli/issues/10922
          // tslint:disable-next-line:no-any
          (process.stdout as any)._handle.setBlocking(true);
          // tslint:disable-next-line:no-any
          (process.stdout as any)._handle.setBlocking(true);
          const bin = os.platform() === 'win32' && binPath === 'ng' ? `${binPath}.cmd` : binPath;
          const childProcess = child_process.spawn(bin, args, {
            env: { ...process.env, ...env },
            cwd: process.cwd(),
            stdio: 'inherit'
          });
      
          childProcess.on('close', (code: number) => {
            // tslint:disable-next-line:triple-equals
            code != 0 ? done(`Process failed with code ${code}`) : done();
          });
        };
      }
    1. package.json下新建build脚本,内容如下:

      json 复制代码
      "scripts":{
       	...
          "build": "gulp build:site",
          ...
      }

      后续每次打包只需执行npm run build脚本,即可实时更新版本号(打包时间)并同步更新页面了。

相关推荐
GDAL3 天前
gulp入门教程14:vinyl
前端·javascript·gulp
GDAL4 天前
gulp入门教程11:series()
gulp
秋雨凉人心1 个月前
Webpack和GuIp打包原理以及不同
开发语言·前端·javascript·webpack·gulp
科技首发2 个月前
从“游戏科学”到玄机科技:《黑神话:悟空》的视角打开动漫宇宙
gulp
我爱吃干果2 个月前
自动化构建工具Gulp
运维·javascript·node.js·自动化·gulp
qq_263_tohua3 个月前
00067期 matlab中的asv文件
gulp
worker..3 个月前
[BSidesCF 2020]Had a bad day1
gulp
worker..3 个月前
[BJDCTF2020]Mark loves cat1
postman·gulp
GDAL5 个月前
gulp入门8:parallel
前端·node.js·gulp
GDAL5 个月前
gulp入门7:task
前端·node.js·gulp