观察,重新编译并重新启动

joc*_*ull 6 node.js gruntjs typescript grunt-contrib-watch

我一直在寻找一种方法的示例,以便在发生文件更改时使用Grunt的监视模块执行几个步骤.我还没有找到任何一个很好的例子,所以如果有人能指出我的方向很好.

  1. 构建TypeScript项目(我有这个工作)
  2. 监视文件更改的目录(这也适用)
  3. 开始在节点进程中运行已编译的JavaScript,同时仍然关注文件更改(通过Grunt执行此操作的最佳方法是什么?监视模块似乎启动了重新编译任务OK)
  4. 在文件更改时,停止其他正在运行的进程,重新编译,并在完成后重新启动.继续关注变化(不知道这个 - 重启是最棘手的部分!)

我尝试了一些不同的方法,例如使用Grunt启动子进程,但我总是最终处理悬空进程,锁定端口,错误的STDIO或其他问题.如果Grunt进程退出,我希望杀死子进程.

有没有一个好方法来处理这个?谢谢!

Ada*_*Cox 11

我的简单实现是通过 package.json 的配置使用nodemon 来观察 src 的 ts 文件更改并使用 tsc 编译 typescript/ts 文件...

package.json 中的“scripts”部分:

  "scripts": {
     "debug": "nodemon -e js,ts --watch src --exec \"yarn run build:ts && yarn run start:app\"",
     "build:ts": "node_modules/.bin/tsc",
     "start:app": "node dist/app"
  },
Run Code Online (Sandbox Code Playgroud)

tsconfig.json

{
   "compilerOptions": {
     "target": "es6",
     "module": "commonjs",
     "outDir": "dist"
   },
   "include": [
     "src/**/*.ts"
   ],
   "exclude": [
     "node_modules"
   ]
}
Run Code Online (Sandbox Code Playgroud)


Phi*_*ert 5

这是我的解决方案。我有一个nodemon监视src文件夹并在看到更改时触发构建周期 + 节点调用。它被称为使用npm run dev:src。这是一个非常简单的解决方案:

package.json

"scripts": {
  ...
  "build:dev": "npm run clean && npm run compile:dev",
  "clean": "rimraf dist",
  "compile": "babel src -d dist && npm run copy:static",
  "compile:dev": "babel src -d dist -s && npm run copy:static",
  "copy:static": "cp -R src/static dist/static",
  "dev:dist": "npm run build:dev && node --inspect dist/server.js",
  "dev:src": "npm run build:dev && nodemon --watch src --exec npm run dev:dist",
}
Run Code Online (Sandbox Code Playgroud)

编辑:

这是一种古老的技术选择。我知道这可能超出范围,但我建议使用这样的 webpack/rollup 方法:

"scripts": {
    "start": "node build/index.js",
    "build": "webpack",
    "dev": "cross-env NODE_ENV=development nodemon --watch src --watch package.* --watch .env --watch .env.development --watch .env.development.local --watch webpack.config.js --exec \"npm run build && node build/index.js\"",
    "lint": "eslint ./src --ext .js && prettier --check ./src/**/*{.js,.mjs}",
    "lint:fix": "eslint ./src --ext .js --fix && prettier --write ./src/**/*{.js,.mjs}",
  },
Run Code Online (Sandbox Code Playgroud)

或强烈考虑 Kent C. Dodds 的方法:

"scripts": {
    "start": "node .",
    "build": "babel --delete-dir-on-start --out-dir dist --copy-files --ignore \"**/__tests__/**,**/__mocks__/**\" --no-copy-ignored src"
  }
Run Code Online (Sandbox Code Playgroud)

https://kentcdodds.com/blog/how-i-structure-express-apps


joc*_*ull 0

我最终不得不推出自己的子进程。Nodemon 将阻止监视发生,并且不够灵活,无法处理重新编译步骤。

这是我的 Gruntfile,使用了 watch、copy、clean 和 TypeScript 模块。

var loader = require('load-grunt-tasks');
var cp = require('child_process');

module.exports = function (grunt) {
  loader(grunt, {});

  grunt.initConfig({
    tsFiles: [
      "**/*.ts",
      "!typings/**/*.ts",
      "typings/tsd.d.ts",
      "!build/**/*.ts",
      "!bower_modules/**/*.ts",
      "!node_modules/**/*.ts",
    ],
    buildDir: 'build/',

    clean: {
      build: '<%= buildDir %>'
    },

    ts: {
      build: {
        src: [
          "**/*.ts",
          "!typings/**/*.ts",
          "typings/tsd.d.ts",
          "!build/**/*.ts",
          "!bower_modules/**/*.ts",
          "!node_modules/**/*.ts",
        ],
        outDir: '<%= buildDir %>',
        options: {
          "target": 'ES5',
          "module": 'commonjs',
          "sourceMap": true,
        }
      }
    },

    copy: {
      build: {
        expand: true,
        cwd: './',
        src: [
          '*.json',
          'config/**/*.json',
          'test/**/*.js'
        ],
        dest: '<%= buildDir %>/',
        filter: 'isFile'
      }
    },

    watch: {
      run: {
        files: [
          '**/*.ts',
          '**/*.js',
          '**/*.json',
          '!.*/**/*.*',
          '!build/**/*.*',
          '!node_modules/**/*.*',
          '!logs/**/*.*'
        ],
        tasks: ['server-stop', 'build', 'server-restart'],
        options: {
          spawn: false
        }
      }
    }
  });

  var child = null;
  function killChild(){
    if (child){
      child.kill();
      child.disconnect();
      child = null;
    }    
  }

  grunt.registerTask('server-stop', 'Stop the dev server', function(){
    killChild();
  });

  grunt.registerTask('server-restart', 'Stop the dev server', function(){
    killChild();
    child = cp.fork('./build/app.js');
  });

  grunt.registerTask('build', ['copy', 'ts']);
  grunt.registerTask('rebuild', ['clean', 'build']);
  grunt.registerTask('default', ['rebuild']);
  grunt.registerTask('run', ['default', 'server-restart', 'watch']);
};
Run Code Online (Sandbox Code Playgroud)