2017-07-26 21 views
2

我們正着手在Angular 2應用中進行國際化/本地化,我希望能夠編寫一些腳本來完成各種任務,例如生成翻譯源文件,構建和/或者用來自特定語言的翻譯來爲應用程序提供服務。從腳本文件而不是從CLI運行Angular CLI腳本?本地化/國際化

與其將腳本寫入package.json文件中,我希望能夠在腳本/目錄中的單獨文件中捕獲腳本,並且package.json文件中的腳本將指向這些腳本。

例如,我想採取這樣的事情在package.json

"scripts": { 

    //other irrelevant scripts 

    "generateXLF": "ng-xi18n --i18nFormat=xlf --outFile=./src/locale/baseFile/messages.xlf", 

    //other irrelevant scripts 
}, 

,而是有這樣的事情:

"scripts": { 

    //other irrelevant scripts 

    "generateXLF": "node ./build/scripts/locale/generateXLF.js" 

    //other irrelevant scripts 
}, 

或代替這樣的:

"scripts": { 

    //other irrelevant scripts 

    "serveLocale": : "./node_modules/.bin/ngc --i18nFile=./src/locale/languages/($someLocaleIPassIn)/messages.($someLocaleIPassIn).xlf --locale=($someLocaleIPassIn) --i18nFormat=xlf", 

    //other irrelevant scripts 
}, 

取而代之的是:

"scripts": { 

    //other irrelevant scripts 

    "serveLocale": : "node ./build/scripts/locale/serveLocale.js $someLocaleIPassIn" 

    //other irrelevant scripts 
}, 

基本上我需要做到以下幾點:可封裝,我通常將不得不與角度CLI一噸的標誌運行/執行命令

  • 編寫腳本。即我怎樣才能運行「ng服務」腳本文件與一堆旗幟?
  • 可以傳遞參數給這些腳本

目前我的存在方式的一部分。例如,在我的generateXLF.js文件目前我只是想經營ng serve,不帶參數或標誌,就像這樣:

var ngServe = require('@angular/cli/commands/serve'); 
new ngServe.default(); 

,但我不斷收到此錯誤:

C:\Projects\MyProject\StyleGuide\node_modules\@angular\cli\ember-cli\lib\models\command.js:77 
    this.isWithinProject = this.project.isEmberCLIProject(); 
           ^

TypeError: Cannot read property 'isEmberCLIProject' of undefined 
    at Class.init (C:\Projects\MyProject\StyleGuide\node_modules\@angular\cli\ember-cli\lib\models\command.js:77:40) 
    at Class.superWrapper [as init] (C:\Projects\MyProject\StyleGuide\node_modules\core-object\lib\assign-properties.js:34:20) 
    at Class.CoreObject (C:\Projects\MyProject\StyleGuide\node_modules\core-object\core-object.js:9:15) 
    at Class (C:\Projects\MyProject\StyleGuide\node_modules\core-object\core-object.js:21:5) 
    at Class (C:\Projects\MyProject\StyleGuide\node_modules\core-object\core-object.js:21:5) 
    at C:\Projects\MyProject\StyleGuide\build\scripts\locale\generateXLF.js:32:5 
    at Object.<anonymous> (C:\Projects\MyProject\StyleGuide\build\scripts\locale\generateXLF.js:37:3) 
    at Module._compile (module.js:570:32) 
    at Object.Module._extensions..js (module.js:579:10) 
    at Module.load (module.js:487:32) 

Process finished with exit code 1 

ng serve作品就好了當我從CLI運行它時,而不是當我嘗試從腳本運行它時。我猜不知道我需要設置腳本文件來知道我的.angular-cli.json文件和我的package.json文件在哪裏,並且使用這些文件中的信息來使ng serve正確地從腳本文件運行。但我可能完全錯誤,爲什麼它失敗。

TLDR:如何成功運行腳本文件中帶有標誌的Angular CLI腳本?如何選擇我已經通過的參數?

回答

2

結束瞭解​​決它。這裏是我的腳本,compileInLocale.js
npm run buildInLocale es
或本:

#! /usr/bin/env node 

const angularCli = require('@angular/cli'); 
const fileSystem = require('fs'); 
const chalk = require('chalk'); 

var command = process.argv.slice(2, 3).toString(); 
var locale = process.argv.slice(3, 4).toString(); 

console.log(chalk.bgBlueBright.bold('Attempting to execute ' + __filename + ' with command "' + 
command + '" and locale "' + locale + '".\n')); 

makeArguments(command, locale); 

/** 
* @name makeArguments 
* @description Create the array of arguments to send to the Angular CLI 
* @param {String} commandToRun the ng command we want to run, such as 'serve' or 'build' 
* @param {String} specifiedLocale the locale that the developer specified when they called 
* the script. For example, the string 'es' from the following command line 
* entry: 'npm run serveInLocale es' 
* @returns {void} Nothing. 
*/ 
function makeArguments(commandToRun, specifiedLocale) { 

var localeFile = './src/locale/languages/' + specifiedLocale + '/messages.' + specifiedLocale + '.xlf'; 

if (fileSystem.existsSync(localeFile)) { 

    /* 
    @TODO: add in logic to build the base translation file, then compare the contents of the 
    @TODO <source> tags in the translation file to the <source> tags in the file we are trying 
    @TODO to serve to see if it is up-to-date. 
    */ 

    var argArray = [ 
     commandToRun, 
     '--aot', 
     '--i18nFile=' + localeFile, 
     '--locale=' + specifiedLocale, 
     '--i18nFormat=xlf' 
    ]; 

    console.log(chalk.bgGreen.bold('Preparing to ' + commandToRun + ' file ' + localeFile + '.\n')); 

    serveInSpecifiedLocale(argArray); 
} 
else { 
    console.log(chalk.bgRed.bold('Cannot ' + commandToRun + ' file ' + localeFile + '. File does not exist!\n')); 
} 
} 

/** 
* @name serveInSpecifiedLocale 
* @description Send an object to the Angular CLI containing our arguments array, and other 
* properties that Angular CLI needs to execute our command. 
* @param {Array} argArray the array of arguments we want to give to the CLI 
* @returns {void} Nothing. 
*/ 
function serveInSpecifiedLocale(argArray) { 

/* 
@TODO: move this to its own file. We will have more scripts in the 
@TODO future which need to send arguments to the Angular CLI. 
*/ 

angularCli({ 
    cliArgs: argArray, 
    inputStream: process.stdin, 
    outputStream: process.stdout 
}); 
} 

用諸如這樣的命令運行它
npm run serveInLocale fr

package.json有這樣的事情:

"serveInLocale": "node ./build/scripts/locale/compileInLocale.js serve", 
"buildInLocale": "node ./build/scripts/locale/compileInLocale.js build"  

取決於您是否輸入buildInLocaleserveInLocale,腳本將以servebuild作爲參數命中,然後將區域設置作爲另一個參數,如果我們有該區域設置的文件,則該腳本將起作用。

旁註:我最終做了一堆工作,無緣無故地弄清楚了這一點。這是沒有意義的,因爲在涉及雙向綁定時,Angular 2中的國際化工具(i18n屬性)無法支持翻譯,因此我們最終將使用類似ngx-translate的東西。我仍想發佈我的解決方案,以防其他人需要編寫腳本讓他們運行通常從CLI運行的腳本。

+0

真棒!這節省了我大量的觀察和學習。 – gye