Cli: [๊ธฐ๋Šฅ] ์ฃผ์„์„ ์œ„ํ•ด package.json์— ๋Œ€ํ•ด jsonc ๋˜๋Š” JSON5 ํ—ˆ์šฉ

์— ๋งŒ๋“  2020๋…„ 02์›” 10์ผ  ยท  4์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: npm/cli

๋ญ? ์™œ

์š”์ฒญ์„ ์ž์„ธํžˆ ์„ค๋ช…

์ข‹๋“  ๋‚˜์˜๋“  package.json ๋‚ด์˜ ์ฝ˜ํ…์ธ ๋Š” ์ ์  ๋” ๋ณต์žกํ•ด์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. npm์˜ ์ดˆ๊ธฐ์— ํŒŒ์ผ์€ ํ”„๋กœ์ ํŠธ/ํŒจํ‚ค์ง€๊ฐ€ ์˜์กดํ•˜๋Š” ์ข…์†์„ฑ์— ๋Œ€ํ•œ ์ผ๋ถ€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์— ๋ถˆ๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ๊ฐ€ ์ ์  ๋” ๋ณต์žกํ•ด์ง€๊ณ  ์ด์ œ ํ…Œ์ŠคํŠธ, ํ”„๋ ˆ์ž„์›Œํฌ, ๊ธฐํƒ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ชจ๋‘ ํ•จ๊ป˜ ์•‰์•„ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ์ข…์†์„ฑ์ž…๋‹ˆ๋‹ค. dependencies ์™€ devDependencies ์™€ ์•ฝ๊ฐ„์˜ ๊ตฌ๋ถ„์ด ์žˆ์—ˆ์ง€๋งŒ ์ด๋Š” ๋Œ€๋žต์ ์ธ ๋ถ„๋ฅ˜์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด์ œ ๋” ๋ณต์žกํ•œ package.json์— ๊ธฐ์—ฌํ•˜๊ณ  ๊ฑฐ์ฃผํ•˜๋Š” ๋„๊ตฌ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค... monorepo ๊ตฌ์„ฑ, lint ๊ตฌ์„ฑ, ์ปค๋ฐ‹ ๊ตฌ์„ฑ, git hooks, nodemon, jest, ๋ชฉ๋ก์€ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค...

์ฃผ์„์€ ๋ชจ๋“  ๋ณต์žก์„ฑ์„ ์„ค๋ช…ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์—ฌ์ „ํžˆ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์œ ์ง€ ๊ด€๋ฆฌ์ž๊ฐ€ ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด ์ˆœ์ˆ˜ JSON์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ, ์ตœ์†Œํ•œ ์ด ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ์ž‘์„ฑ์ž(๋Œ€๋‹ค์ˆ˜ ์‚ฌ์šฉ์ž)๊ฐ€ ์ž์‹ ์˜ package.json์„ ๋ฌธ์„œํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  json์€ ์ค‘๋ณต ํ‚ค๋ฅผ ์ฃผ์„์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๊ฒƒ์€ ๋„ˆ๋ฌด ํ•ดํ‚น์ฒ˜๋Ÿผ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค.

์–ด๋–ป๊ฒŒ

ํ˜„์žฌ ํ–‰๋™

์ˆ˜์ •๋˜๊ณ  ์ธ์œ„์ ์ธ ์˜ˆ:

{
  "name": "my-project",
  "version": "0.0.1",
  "license": "MIT",
  "scripts": {
    "build": "a bunch of scripts",
    "ci": "a bunch of scripts",
    "ci:local": "a bunch of scripts",
    "docsite": "a bunch of scripts",
    "docsite:combiner": "a bunch of scripts",
    "docsite:sassdoc": "a bunch of scripts",
    "docsite:tsdoc": "a bunch of scripts",
    "e2e": "a bunch of scripts",
    "html-sketchapp-install": "a bunch of scripts",
    "html-sketchapp": "a bunch of scripts",
    "lint": "a bunch of scripts",
    "sassdoc": "a bunch of scripts",
    "sassdoc:comp": "a bunch of scripts",
    "sassdoc:core": "a bunch of scripts",
    "start": "a bunch of scripts",
    "start:hmr": "a bunch of scripts",
    "start:qa": "a bunch of scripts",
    "start:dev": "a bunch of scripts",
    "generate-examples": "a bunch of scripts",
    "rebuild-markdown": "a bunch of scripts",
    "watch-examples": "a bunch of scripts",
    "test:cov": "a bunch of scripts",

    "test": "jest",
    "test:watch": "jest --watch",
    "test:cc": "jest --coverage"
  },
  "config": {
    "commitizen": {
      "path": "./node_modules/cz-conventional-changelog"
    }
  },
  "dependencies": {
    "@angular-devkit/build-angular": "~0.900.1",
    "@angular-devkit/build-ng-packagr": "~0.900.1",
    "@angular-devkit/core": "~9.0.0",
    "@angular-devkit/schematics": "~9.0.0",
    "@angular/animations": "~9.0.0",
    "@angular/cdk": "~9.0.0",
    "@angular/cli": "~9.0.1",
    "@angular/common": "~9.0.0",
    "@angular/compiler": "~9.0.0",
    "@angular/compiler-cli": "~9.0.0",
    "@angular/core": "~9.0.0",
    "@angular/forms": "~9.0.0",
    "@angular/language-service": "~9.0.0",
    "@angular/platform-browser": "~9.0.0",
    "@angular/platform-browser-dynamic": "~9.0.0",
    "@angular/router": "~9.0.0",
    "@angular/service-worker": "~9.0.0",
    "@angularclass/hmr": "2.1.3",
    "@ngrx/effects": "~8.6.0",
    "@ngrx/entity": "~8.6.0",
    "@ngrx/router-store": "~8.6.0",
    "@ngrx/schematics": "~8.6.0",
    "@ngrx/store": "~8.6.0",
    "@ngrx/store-devtools": "~8.6.0",
    "@types/jasmine": "~3.5.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/lodash-es": "^4.17.3",
    "@types/node": "^12.11.1",
    "classlist.js": "1.1.20150312",
    "codelyzer": "^5.1.2",
    "console-polyfill": "0.3.0",
    "core-js": "^2.5.4",
    "cz-conventional-changelog": "1.2.0",
    "date-fns": "1.30.1",
    "highcharts": "^7.2.1",
    "highcharts-angular": "^2.4.0",
    "html2canvas": "^1.0.0-rc.5",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~2.1.0",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.2",
    "lodash-es": "^4.17.11",
    "mime": "~2.4.2",
    "ngrx-store-freeze": "0.2.4",
    "ngx-monaco-editor": "~8.0.0",
    "ngx-quill": "^7.3.12",
    "pdfmake": "^0.1.64",
    "prettier": "1.19.1",
    "protractor": "~5.4.3",
    "quill": "^1.3.7",
    "rxjs": "~6.5.4",
    "rxjs-compat": "^6.0.0",
    "standard-changelog": "1.0.19",
    "svgxuse": "1.2.6",
    "ts-node": "~8.3.0",
    "tsickle": "^0.35.0",
    "tslib": "^1.10.0",
    "tslint": "~5.18.0",
    "typescript": "~3.7.5",
    "web-animations-js": "~2.3.1",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@types/jest": "^24.0.6",
    "jest": "^24.1.0",
    "jest-preset-angular": "^6.0.2",
    "ts-node": "~7.0.1",
    "typescript": "3.2.4"
  },
  "jest": {
    "preset": "jest-preset-angular",
    "setupTestFrameworkScriptFile": "<rootDir>/setupJest.ts"
  },
  "nodemonConfig": {
    "ignore": [
      "**/example-module.ts"
    ],
    "watch": [
      "./a/bunch/of/stuff"
    ],
    "ext": "js ts md html"
  },
  "workspaces": {
    "packages": [
      "packages/*"
    ],
    "nohoist": [
      "**"
    ]
  }
}

์˜ˆ์ƒ๋˜๋Š” ๋™์ž‘

์ฃผ์„์ด ์žˆ๋Š” package.json์˜ ์˜ˆ.

{
  "name": "my-project",
  "version": "0.0.1",
  "license": "MIT",
  "scripts": {
    "build": "a bunch of scripts",
    "ci": "a bunch of scripts",
    "ci:local": "a bunch of scripts",
    // for building our documentation site
    "docsite": "a bunch of scripts",
    "docsite:combiner": "a bunch of scripts",
    "docsite:sassdoc": "a bunch of scripts",
    "docsite:tsdoc": "a bunch of scripts",
    "e2e": "a bunch of scripts",
    "lint": "a bunch of scripts",
    "sassdoc": "a bunch of scripts",
    "sassdoc:comp": "a bunch of scripts",
    "sassdoc:core": "a bunch of scripts",
    "start": "a bunch of scripts",
    "start:hmr": "a bunch of scripts",
    "start:qa": "a bunch of scripts",
    "start:dev": "a bunch of scripts",
    "generate-examples": "a bunch of scripts",
    "rebuild-markdown": "a bunch of scripts",
    "watch-examples": "a bunch of scripts",
    "test:cov": "a bunch of scripts",

    "test": "jest",
    "test:watch": "jest --watch",
    "test:cc": "jest --coverage"
  },
  "config": {
    "commitizen": {
      "path": "./node_modules/cz-conventional-changelog"
    }
  },
  "dependencies": {
    // ANGULAR
    "@angular-devkit/build-angular": "~0.900.1",
    "@angular-devkit/build-ng-packagr": "~0.900.1",
    "@angular-devkit/core": "~9.0.0",
    "@angular-devkit/schematics": "~9.0.0",
    "@angular/animations": "~9.0.0",
    "@angular/cdk": "~9.0.0",
    "@angular/cli": "~9.0.1",
    "@angular/common": "~9.0.0",
    "@angular/compiler": "~9.0.0",
    "@angular/compiler-cli": "~9.0.0",
    "@angular/core": "~9.0.0",
    "@angular/forms": "~9.0.0",
    "@angular/language-service": "~9.0.0",
    "@angular/platform-browser": "~9.0.0",
    "@angular/platform-browser-dynamic": "~9.0.0",
    "@angular/router": "~9.0.0",
    "@angular/service-worker": "~9.0.0",
    "@angularclass/hmr": "2.1.3",

    "zone.js": "~0.10.2",
    "rxjs": "~6.5.4",
    "rxjs-compat": "^6.0.0",


    // polyfills for angular 
    "console-polyfill": "0.3.0",
    "core-js": "^2.5.4",
    "classlist.js": "1.1.20150312",
    "svgxuse": "1.2.6",
    "web-animations-js": "~2.3.1",

    // lint management

    "codelyzer": "^5.1.2",
    "prettier": "1.19.1",
    "tslint": "~5.18.0",

    // changelog creation
    "cz-conventional-changelog": "1.2.0",
    "standard-changelog": "1.0.19",

    // ngrx state management 
    "@ngrx/effects": "~8.6.0",
    "@ngrx/entity": "~8.6.0",
    "@ngrx/router-store": "~8.6.0",
    "@ngrx/schematics": "~8.6.0",
    "@ngrx/store": "~8.6.0",
    "@ngrx/store-devtools": "~8.6.0",
    "ngrx-store-freeze": "0.2.4",


    // library deps

    // Graphs support
    "highcharts": "^7.2.1",
    "highcharts-angular": "^2.4.0",

    // for creating pdfs
    "html2canvas": "^1.0.0-rc.5",
    "pdfmake": "^0.1.64",

    // rich text support
    "ngx-quill": "^7.3.12",
    "quill": "^1.3.7",




    // testing
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~2.1.0",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.2",

    // e2e testing
    "protractor": "~5.4.3",

    // typscript and compilation
    "ts-node": "~8.3.0",
    "tsickle": "^0.35.0",
    "tslib": "^1.10.0",
    "typescript": "~3.7.5",

    // misc deps
    "date-fns": "1.30.1",
    "lodash-es": "^4.17.11",
    "mime": "~2.4.2"
  },
  "devDependencies": {
    "@types/jasmine": "~3.5.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/lodash-es": "^4.17.3",
    "@types/node": "^12.11.1",
    "@types/jest": "^24.0.6",
    "jest": "^24.1.0",
    "jest-preset-angular": "^6.0.2",
    "ts-node": "~7.0.1",
    "typescript": "3.2.4"
  },
  // complicated jest configuration here
  "jest": {
    "preset": "jest-preset-angular",
    "setupTestFrameworkScriptFile": "<rootDir>/setupJest.ts"
  },
  // use nodemon to trigger stuff
  "nodemonConfig": {
    "ignore": [
      "**/example-module.ts"
    ],
    "watch": [
      "./a/bunch/of/stuff"
    ],
    "ext": "js ts md html"
  },
  // extra libraries we are creating internally
  "workspaces": {
    "packages": [
      "packages/*"
    ],
    "nohoist": [
      "**"
    ]
  }
}

์ฐธ๊ณ ๋ฌธํ—Œ

์˜ˆ * #0์— ๊ด€๋ จ๋จ * #0์— ๋”ฐ๋ผ ๋‹ค๋ฆ„ * #0์— ์˜ํ•ด ์ฐจ๋‹จ๋จ

https://github.com/microsoft/node-jsonc-parser

Typescript๋Š” tsconfig.json ํŒŒ์ผ์—์„œ ์ฃผ์„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Enhancement

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์€ ์ •์˜์ƒ ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ •์ƒ์ ์ธ ํ˜„์ƒ์ด ์•„๋‹ˆ๋ฉฐ ์†Œํ”„ํŠธ์›จ์–ด์˜ ์ง„ํ™”๊ฐ€ ์ง„ํ–‰๋˜๋Š” ํŠน์„ฑ์— ์žˆ์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

package.json ๋ฅผ ๋กœ๋“œํ•˜๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„œ ํŒจํ‚ค์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  JSON ๋ฅผ JSON5 ๋ฐ”๊พธ๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ๋งค์šฐ ์‰ฝ๊ฒŒ ์ˆ˜์ •๋˜๋Š” ๊ฒƒ ์™ธ์—๋„ API๋Š” ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

Babel์€ ์–ผ๋งˆ ์ „์— JSON5 ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ๊ณ  ์ปค๋ฎค๋‹ˆํ‹ฐ๋Š” ์•ž์œผ๋กœ ๋‚˜์•„๊ฐ€ ์‹œ๊ฐ„์ด ์ „ํ˜€ ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š” ์ด๋Ÿฌํ•œ ์ž‘์€ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. JSON5์˜ ๊ฐœ์„  ์‚ฌํ•ญ์€ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€๋กœ ์œ ๊ธฐ์ ์œผ๋กœ ํ™•์‚ฐ๋˜๊ณ  ๋ฌธ์„œ ๊ฐœ์„  ์‚ฌํ•ญ์€ ํ”„๋กœ์ ํŠธ๋กœ ํ™•์‚ฐ๋ฉ๋‹ˆ๋‹ค.

์ข‹์€ ์ผ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

IMO, ์•ž์œผ๋กœ ๋‚˜์•„๊ฐ€์ง€ ์•Š๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๋ณ€๋ช…์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๋” ๋งŽ์€ ๋ณต์žก์„ฑ/ํ˜ผ๋ˆ์„ ์ถ”๊ฐ€ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

๋ชจ๋“  4 ๋Œ“๊ธ€

@admosity ๋ถˆํ–‰ํžˆ๋„ ์ด๊ฒƒ์€ ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ƒˆ๋กœ์šด ๊ตฌ๋ฌธ์„ ์ดํ•ดํ•˜๋ ค๋ฉด package.json๊ณผ ๋งŽ์€ npm ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค๋ฅธ ๋ชจ๋“  ์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค...

์ด๊ฒƒ์€ ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋‘ ๊ฐœ์˜ ํŒŒ์ผ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํŒจํ‚ค์ง€.json
ํŒจํ‚ค์ง€.json5

์‚ฌ์šฉ์ž๋Š” package.json5๋ฅผ ํŽธ์ง‘ํ•˜์—ฌ ์ฃผ์„์„ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. Npm์€ package.json์„ ์ƒ์„ฑ(๋˜๋Š” ์žฌ์ •์˜)ํ•˜๊ณ  package.json5์˜ ์ฃผ์„์„ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์€ ์ •์˜์ƒ ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ •์ƒ์ ์ธ ํ˜„์ƒ์ด ์•„๋‹ˆ๋ฉฐ ์†Œํ”„ํŠธ์›จ์–ด์˜ ์ง„ํ™”๊ฐ€ ์ง„ํ–‰๋˜๋Š” ํŠน์„ฑ์— ์žˆ์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

package.json ๋ฅผ ๋กœ๋“œํ•˜๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„œ ํŒจํ‚ค์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  JSON ๋ฅผ JSON5 ๋ฐ”๊พธ๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ๋งค์šฐ ์‰ฝ๊ฒŒ ์ˆ˜์ •๋˜๋Š” ๊ฒƒ ์™ธ์—๋„ API๋Š” ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

Babel์€ ์–ผ๋งˆ ์ „์— JSON5 ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ๊ณ  ์ปค๋ฎค๋‹ˆํ‹ฐ๋Š” ์•ž์œผ๋กœ ๋‚˜์•„๊ฐ€ ์‹œ๊ฐ„์ด ์ „ํ˜€ ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š” ์ด๋Ÿฌํ•œ ์ž‘์€ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. JSON5์˜ ๊ฐœ์„  ์‚ฌํ•ญ์€ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€๋กœ ์œ ๊ธฐ์ ์œผ๋กœ ํ™•์‚ฐ๋˜๊ณ  ๋ฌธ์„œ ๊ฐœ์„  ์‚ฌํ•ญ์€ ํ”„๋กœ์ ํŠธ๋กœ ํ™•์‚ฐ๋ฉ๋‹ˆ๋‹ค.

์ข‹์€ ์ผ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

IMO, ์•ž์œผ๋กœ ๋‚˜์•„๊ฐ€์ง€ ์•Š๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๋ณ€๋ช…์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๋” ๋งŽ์€ ๋ณต์žก์„ฑ/ํ˜ผ๋ˆ์„ ์ถ”๊ฐ€ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰