TR kizaki Tech Memo

management to nodebrew by Volta => Typescript install to local env

ref: howto-volta-useit <= 最高。神。

問題点 他のnode管理ツールを使って自在にバージョン切り替えはできても、システム全体が同じバージョンになる globalインストールしたアプリケーションはインストールしたバージョンに切り替えないと使えない

typescriptの動作確認をしたところ、nodeのversionが古いままでglobal installしてしまった。古いnodeじゃないと動作しないなど後々影響が出そうだからupgradeしたい。 あと、以前nodev14.18じゃないと動作しないprojectがあったから、nodeのversion controllもしたい。

wallet-tutorial git:(main) ✗ npm install -g typescript
/Users/$HOME/.nodebrew/node/v14.18.2/bin/tsc -> /Users/$HOME/.nodebrew/node/v14.18.2/lib/node_modules/typescript/bin/tsc
/Users/$HOME/.nodebrew/node/v14.18.2/bin/tsserver -> /Users/$HOME/.nodebrew/node/v14.18.2/lib/node_modules/typescript/bin/tsserver
typescript@4.6.4
added 1 package from 1 contributor in 2.878s

╭───────────────────────────────────────────────────────────────╮ │ │ │ New major version of npm available! 6.14.15 → 8.8.0 │ │ Changelog: https://github.com/npm/cli/releases/tag/v8.8.0 │ │ Run npm install -g npm to update! │ │ │ ╰───────────────────────────────────────────────────────────────╯

➜  wallet-tutorial git:(main) ✗ tsc hello.ts
➜  wallet-tutorial git:(main) ✗ ls
[README.md](http://readme.md/)      hello.js       next.config.js pages          tsconfig.json
components     hello.ts       node_modules   public         utils
context        next-env.d.ts  package.json   styles         yarn.lock
➜  wallet-tutorial git:(main) ✗ node hello.js
Hello
➜  wallet-tutorial git:(main) ✗ npm -v
6.14.15
➜  wallet-tutorial git:(main) ✗ node -v
v14.18.2

brewでuninstallしてもversion残っているんだが?

➜  wallet-tutorial git:(main) ✗ brew uninstall node
Uninstalling /usr/local/Cellar/node/18.0.0... (1,929 files, 49.0MB)
➜  wallet-tutorial git:(main) ✗ node -v
v14.18.2

voltaというnodeのversion controll toolを見つけたのでinstall

wallet-tutorial git:(main) ✗ brew install volta
Running brew update --preinstall...
==> Auto-updated Homebrew!
Updated 3 taps (homebrew/core, homebrew/cask and homebrew/services).
==> New Formulae
bartib                     libxcrypt                  sqls
ddh                        micro_inetd                vcluster
hut                        spirv-headers              wb32-dfu-updater_cli
==> Updated Formulae
Updated 435 formulae.
==> New Casks
fmail2                     osu                        vertcoin-core
==> Updated Casks
Updated 246 casks.
==> Deleted Casks
biopassfido                lego-digital-designer      srware-iron
bootchamp                  multiscan-3b               thought-train
firestormos                mxsrvs                     vin047-abgx360
flip4mac                   piskel                     zoom-outlook-plugin
flvcd-bigrats              sitebulb
==> Downloading https://ghcr.io/v2/homebrew/core/volta/manifests/1.0.7
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/volta/blobs/sha256:2dc96b13b565
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sh
######################################################################## 100.0%
==> Pouring volta--1.0.7.monterey.bottle.tar.gz
==> Caveats
zsh completions have been installed to:
/usr/local/share/zsh/site-functions
==> Summary
🍺  /usr/local/Cellar/volta/1.0.7: 12 files, 16.8MB
==> Running brew cleanup volta...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see man brew).
➜  wallet-tutorial git:(main) ✗ volta -v
Updating your Volta directory. This may take a few moments...
1.0.7
➜  wallet-tutorial git:(main) ✗ volta setup
success: Setup complete. Open a new terminal to start using Volta!

早速最新版のnodeをinstall via voltaもerror

➜  wallet-tutorial git:(main) ✗ volta install node

error: Could not unpack Node v16.15.0

Please ensure the correct version is specified.
Error details written to /Users/$HOME/.volta/log/volta-error-2022-05-01_11_41_12.402.log

node強制インストールのあとにsuccess install via volta( これはprojectに紐付いたのが@16.15.0なのかも)

➜  wallet-tutorial git:(main) ✗ brew uninstall --force node
➜  wallet-tutorial git:(main) ✗ node -v
v14.18.2
➜  wallet-tutorial git:(main) ✗ volta install node
success: installed and set node@16.15.0 (with npm@8.5.5) as default

まだグローバルでは古いバージョン。これを@16.15.0にしたい

➜  wallet-tutorial git:(main) ✗ node -v
v14.18.2

利用可能なversion検索

wallet-tutorial git:(main) ✗ nodebrew ls
v14.17.2
v14.18.2
v16.2.0
v16.13.1

current: v14.18.2

利用可能なversion一覧

wallet-tutorial git:(main) ✗ nodebrew ls-remote

v16.0.0   v16.1.0   v16.2.0   v16.3.0   v16.4.0   v16.4.1   v16.4.2   v16.5.0
v16.6.0   v16.6.1   v16.6.2   v16.7.0   v16.8.0   v16.9.0   v16.9.1   v16.10.0
v16.11.0  v16.11.1  v16.12.0  v16.13.0  v16.13.1  v16.13.2  v16.14.0  v16.14.1
v16.14.2  v16.15.0

v17.0.0   v17.0.1   v17.1.0   v17.2.0   v17.3.0   v17.3.1   v17.4.0   v17.5.0
v17.6.0   v17.7.0   v17.7.1   v17.7.2   v17.8.0   v17.9.0

v18.0.0

voltaのpin機能を使ってnodeのversionを固定。project内は固定できてもglobalに影響なし

wallet-tutorial git:(main) ✗ volta pin node@16
success: pinned node@16.15.0 (with npm@8.5.5) in package.json
➜  wallet-tutorial git:(main) ✗ node -v
v14.18.2

.nodebrewのglobal依存関係をcheck。直接依存しているのはtypescriptとyarn

➜  wallet-tutorial git:(main) ✗  npm list -g
/Users/$HOME/.nodebrew/node/v14.18.2/lib
├─┬ npm@6.14.15
-omitted-
├── typescript@4.6.4
└── yarn@1.22.17

voltaを使用していきたいのでnodebrewの~/.nodebrew以下のcurrentやnodeを削除 そのあとにproject内のversion確認

➜  wallet-tutorial git:(main) ✗ source ~/.zshrc
➜  wallet-tutorial git:(main) ✗ node -v
v16.15.0

globalのversionも確認

➜  ~ git:(main) ✗ node -v
v16.15.0

update成功!

voltaでnodeやそれに付随するnpmが管理できているのを確認。npmのupdateにも成功

~ git:(main) ✗ npm list -g
/Users/$HOME/.volta/tools/image/node/16.15.0/lib
├── corepack@0.10.0
└── npm@8.5.5

yarnもvoltaでinstall (version古いわ)

➜  ~ git:(main) ✗ volta install yarn
success: installed and set yarn@1.22.18 as default

whichでnodeの場所確認

~ git:(main) ✗ which node
/Users/$HOME/.volta/bin/node

➜  ~ git:(main) ✗ volta which node
/Users/$HOME/.volta/tools/image/node/16.15.0/bin/node

whichでyarnの場所確認

➜  ~ git:(main) ✗ which yarn
/Users/$HOME/.volta/bin/yarn
➜  ~ git:(main) ✗ volta which yarn
/Users/$HOME/.volta/tools/image/yarn/1.22.18/bin/yarn

npmの最新バージョンをvoltaでinstallしてもglobalに反映させる

~ git:(main) ✗ volta install npm@8.8.0
success: installed and set npm@8.8.0 as default

succcess

➜  ~ git:(main) ✗ volta list npm
⚡️ Custom npm versions in your toolchain:

v8.8.0 (default)

~ git:(main) ✗ npm -v
8.8.0

typescriptを再インストール。今度はglobalじゃなくてlocalでinstallするのだ。初心者クリアした気持ち。 dirctory作ってnpm initでpackage jsonを作成

➜  devtool git:(main) ✗ cd Typescript
➜  Typescript git:(main) ✗ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (typescript)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/$HOME/devtool/Typescript/package.json:

{
"name": "typescript",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

Is this OK? (yes)
npm notice
npm notice New minor version of npm available! 8.5.5 -> 8.8.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v8.8.0
npm notice Run npm install -g npm@8.8.0 to update!
npm notice

typescriptをローカルインストール

Typescript git:(main) ✗ npm install --save-dev typescript

added 1 package, and audited 2 packages in 2s

found 0 vulnerabilities

versionの確認

Typescript git:(main) ✗ ./node_modules/.bin/tsc --version
Version 4.6.4

compiler option fileの作成

Typescript git:(main) ✗ ./node_modules/.bin/tsc --init

Created a new tsconfig.json with:
TS
target: es2016
module: commonjs
strict: true
esModuleInterop: true
skipLibCheck: true
forceConsistentCasingInFileNames: true

You can learn more at https://aka.ms/tsconfig.json

動作確認はOKなので一旦ディレクトリまるごと削除してやり直し

~ git:(main) ✗ rm -rf wallet-tutorial

ref:390647a7c26933940470 このtutorialでやる

➜  devtool git:(main) ✗ mkdir tsconfig; cd tsconfig
➜  tsconfig git:(main) ✗ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (tsconfig)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/$HOME/devtool/tsconfig/package.json:

{
"name": "tsconfig",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

Is this OK? (yes)

➜  tsconfig git:(main) ✗ npm install --save-dev typescript

added 1 package, and audited 2 packages in 1s

found 0 vulnerabilities

➜ tsconfig git:(main) ✗ npx tsc --init (npxのすごいところ。--save-dev typescriptのようにlocal構築したtypescriptも起動してくれる。 この状態で tscだけだとコマンド起動しない。globalのみ。ローカル信者としてはnpxは神。) NPX — A tool to run node packages easily without installing binaries.

Created a new tsconfig.json with:
TS
target: es2016
module: commonjs
strict: true
esModuleInterop: true
skipLibCheck: true
forceConsistentCasingInFileNames: true

You can learn more at https://aka.ms/tsconfig.json

➜  tsconfig git:(main) ✗ ls -1
node_modules
package-lock.json
package.json
tsconfig.json

生成されたfileの確認

➜  tsconfig git:(main) ✗ ls
node_modules      package-lock.json package.json      tsconfig.json

typescriptからjavascript file生成してみた。

➜  tsconfig git:(main) ✗ touch hello.ts
➜  tsconfig git:(main) ✗ vi hello.ts
tsconfig git:(main) ✗ npx tsc hello.ts
➜  tsconfig git:(main) ✗ ls
hello.js          node_modules      package.json
hello.ts          package-lock.json tsconfig.json

nodeが正しく動いた

tsconfig git:(main) ✗ node hello.js
Hello! TypeScript!

Webpackなどツール類のインストール

ref: efdaa0ae7d8c972c8103

tsconfig git:(main) ✗ npm install typescript ts-loader webpack webpack-cli webpack-dev-server --save-dev

added 319 packages, and audited 321 packages in 19s

36 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

package.jsonに追加

"npm start"コマンドで、webpack-dev-serverを起動するようにする。 "npm run build"コマンドで、Webpackのビルド処理を起動するようにする。

tsconfig git:(main) ✗ cat package.json
{
"name": "tsconfig",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode=development",
"start": "webpack serve --mode=development"
},
"author": "",
"license": "ISC",
"devDependencies": {
"ts-loader": "^9.3.0",
"typescript": "^4.6.4",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.8.1"
}
}

Webpack用の設定ファイル webpack.config.js作成

tsconfig git:(main) ✗ touch webpack.config.js
➜  tsconfig git:(main) ✗ vi webpack.config.js

const path = require('path');
module.exports = {
// モジュールバンドルを行う起点となるファイルの指定
// 指定できる値としては、ファイル名の文字列や、それを並べた配列やオブジェクト
// 下記はオブジェクトとして指定した例
entry: {
bundle: './src/app.ts'
},
output: {
// モジュールバンドルを行った結果を出力する場所やファイル名の指定
// "__dirname"はこのファイルが存在するディレクトリを表すnode.jsで定義済みの定数
path: path.join(__dirname,'dist'),
filename: '[name].js'  // [name]はentryで記述した名前(この例ではbundle)が入る
},
// モジュールとして扱いたいファイルの拡張子を指定する
// 例えば「import Foo from './foo'」という記述に対して"foo.ts"という名前のファイルをモジュールとして探す
// デフォルトは['.js', '.json']
resolve: {
extensions:['.ts','.js']
},
devServer: {
// webpack-dev-serverの公開フォルダ
static: {
directory: path.join(__dirname, "dist"),
},
},
// モジュールに適用するルールの設定(ここではローダーの設定を行う事が多い)
module: {
rules: [
{
// 拡張子が.tsで終わるファイルに対して、TypeScriptコンパイラを適用する
test:/\.ts$/,loader:'ts-loader'
}
]
}
}

起動したけど反映されない。

➜  dist git:(main) ✗ npm start

> tsconfig@1.0.0 start
webpack serve --mode=development
> 

<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost:8080/
<i> [webpack-dev-server] On Your Network (IPv4): http://192.168.100.138:8080/
<i> [webpack-dev-server] On Your Network (IPv6): http://[fe80::1]:8080/
<i> [webpack-dev-server] Content not from webpack is served from '/Users/$HOME/devtool/tsconfig/dist' directory
asset bundle.js 240 KiB [emitted] (name: bundle)
runtime modules 27.3 KiB 12 modules
modules by path ./node_modules/ 157 KiB
modules by path ./node_modules/webpack-dev-server/client/ 52.4 KiB 12 modules
modules by path ./node_modules/webpack/hot/*.js 4.3 KiB
./node_modules/webpack/hot/dev-server.js 1.59 KiB [built] [code generated]
+ 3 modules
modules by path ./node_modules/html-entities/lib/*.js 81.3 KiB
./node_modules/html-entities/lib/index.js 7.74 KiB [built] [code generated]
./node_modules/html-entities/lib/named-references.js 72.7 KiB [built] [code generated]
+ 2 modules
./node_modules/ansi-html-community/index.js 4.16 KiB [built] [code generated]
./node_modules/events/events.js 14.5 KiB [built] [code generated]
modules by path ./src/*.ts 639 bytes
./src/app.ts 238 bytes [built] [code generated]
./src/item.ts 401 bytes [built] [code generated]
webpack 5.72.0 compiled successfully in 1594 ms

最後にtsconfig.jsonの全オプションを理解する

➜  tsconfig git:(main) ✗ cat tsconfig.json
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */

/* Projects / // "incremental": true, / Enable incremental compilation / // "composite": true, / Enable constraints that allow a TypeScript project to be used with project references. / // "tsBuildInfoFile": "./", / Specify the folder for .tsbuildinfo incremental compilation files. / // "disableSourceOfProjectReferenceRedirect": true, / Disable preferring source files instead of declaration files when referencing composite projects / // "disableSolutionSearching": true, / Opt a project out of multi-project reference checking when editing. / // "disableReferencedProjectLoad": true, / Reduce the number of projects loaded automatically by TypeScript. */

/* Language and Environment / "target": "es2016", / Set the JavaScript language version for emitted JavaScript and include compatible library declarations. / // "lib": [], / Specify a set of bundled library declaration files that describe the target runtime environment. / // "jsx": "preserve", / Specify what JSX code is generated. / // "experimentalDecorators": true, / Enable experimental support for TC39 stage 2 draft decorators. / // "emitDecoratorMetadata": true, / Emit design-type metadata for decorated declarations in source files. / // "jsxFactory": "", / Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' / // "jsxFragmentFactory": "", / Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. / // "jsxImportSource": "", / Specify module specifier used to import the JSX factory functions when using jsx: react-jsx*.*/ // "reactNamespace": "", /* Specify the object invoked forcreateElement. This only applies when targeting react` JSX emit. / // "noLib": true, / Disable including any library files, including the default lib.d.ts. / // "useDefineForClassFields": true, / Emit ECMAScript-standard-compliant class fields. */

/* Modules / "module": "commonjs", / Specify what module code is generated. / // "rootDir": "./", / Specify the root folder within your source files. / // "moduleResolution": "node", / Specify how TypeScript looks up a file from a given module specifier. / // "baseUrl": "./", / Specify the base directory to resolve non-relative module names. / // "paths": {}, / Specify a set of entries that re-map imports to additional lookup locations. / // "rootDirs": [], / Allow multiple folders to be treated as one when resolving modules. / // "typeRoots": [], / Specify multiple folders that act like ./node_modules/@types. / // "types": [], / Specify type package names to be included without being referenced in a source file. / // "allowUmdGlobalAccess": true, / Allow accessing UMD globals from modules. / // "resolveJsonModule": true, / Enable importing .json files / // "noResolve": true, / Disallow imports, requires or <reference>s from expanding the number of files TypeScript should add to a project. */

/* JavaScript Support / // "allowJs": true, / Allow JavaScript files to be a part of your program. Use the checkJS option to get errors from these files. / // "checkJs": true, / Enable error reporting in type-checked JavaScript files. / // "maxNodeModuleJsDepth": 1, / Specify the maximum folder depth used for checking JavaScript files from node_modules. Only applicable with allowJs. */

/* Emit / // "declaration": true, / Generate .d.ts files from TypeScript and JavaScript files in your project. / // "declarationMap": true, / Create sourcemaps for d.ts files. / // "emitDeclarationOnly": true, / Only output d.ts files and not JavaScript files. / // "sourceMap": true, / Create source map files for emitted JavaScript files. / // "outFile": "./", / Specify a file that bundles all outputs into one JavaScript file. If declaration is true, also designates a file that bundles all .d.ts output. / // "outDir": "./", / Specify an output folder for all emitted files. / // "removeComments": true, / Disable emitting comments. / // "noEmit": true, / Disable emitting files from a compilation. / // "importHelpers": true, / Allow importing helper functions from tslib once per project, instead of including them per-file. / // "importsNotUsedAsValues": "remove", / Specify emit/checking behavior for imports that are only used for types / // "downlevelIteration": true, / Emit more compliant, but verbose and less performant JavaScript for iteration. / // "sourceRoot": "", / Specify the root path for debuggers to find the reference source code. / // "mapRoot": "", / Specify the location where debugger should locate map files instead of generated locations. / // "inlineSourceMap": true, / Include sourcemap files inside the emitted JavaScript. / // "inlineSources": true, / Include source code in the sourcemaps inside the emitted JavaScript. / // "emitBOM": true, / Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. / // "newLine": "crlf", / Set the newline character for emitting files. / // "stripInternal": true, / Disable emitting declarations that have @internal in their JSDoc comments. / // "noEmitHelpers": true, / Disable generating custom helper functions like __extends in compiled output. / // "noEmitOnError": true, / Disable emitting files if any type checking errors are reported. / // "preserveConstEnums": true, / Disable erasing const enum declarations in generated code. / // "declarationDir": "./", / Specify the output directory for generated declaration files. / // "preserveValueImports": true, / Preserve unused imported values in the JavaScript output that would otherwise be removed. */

/* Interop Constraints / // "isolatedModules": true, / Ensure that each file can be safely transpiled without relying on other imports. / // "allowSyntheticDefaultImports": true, / Allow 'import x from y' when a module doesn't have a default export. / "esModuleInterop": true, / Emit additional JavaScript to ease support for importing CommonJS modules. This enables allowSyntheticDefaultImports for type compatibility. / // "preserveSymlinks": true, / Disable resolving symlinks to their realpath. This correlates to the same flag in node. / "forceConsistentCasingInFileNames": true, / Ensure that casing is correct in imports. */

/* Type Checking / "strict": true, / Enable all strict type-checking options. / // "noImplicitAny": true, / Enable error reporting for expressions and declarations with an implied any type.. / // "strictNullChecks": true, / When type checking, take into account null and undefined. / // "strictFunctionTypes": true, / When assigning functions, check to ensure parameters and the return values are subtype-compatible. / // "strictBindCallApply": true, / Check that the arguments for bind, call, and apply methods match the original function. / // "strictPropertyInitialization": true, / Check for class properties that are declared but not set in the constructor. / // "noImplicitThis": true, / Enable error reporting when this is given the type any. / // "useUnknownInCatchVariables": true, / Type catch clause variables as 'unknown' instead of 'any'. / // "alwaysStrict": true, / Ensure 'use strict' is always emitted. / // "noUnusedLocals": true, / Enable error reporting when a local variables aren't read. / // "noUnusedParameters": true, / Raise an error when a function parameter isn't read / // "exactOptionalPropertyTypes": true, / Interpret optional property types as written, rather than adding 'undefined'. / // "noImplicitReturns": true, / Enable error reporting for codepaths that do not explicitly return in a function. / // "noFallthroughCasesInSwitch": true, / Enable error reporting for fallthrough cases in switch statements. / // "noUncheckedIndexedAccess": true, / Include 'undefined' in index signature results / // "noImplicitOverride": true, / Ensure overriding members in derived classes are marked with an override modifier. / // "noPropertyAccessFromIndexSignature": true, / Enforces using indexed accessors for keys declared using an indexed type / // "allowUnusedLabels": true, / Disable error reporting for unused labels. / // "allowUnreachableCode": true, / Disable error reporting for unreachable code. */

/* Completeness / // "skipDefaultLibCheck": true, / Skip type checking .d.ts files that are included with TypeScript. / "skipLibCheck": true / Skip type checking all .d.ts files. */ } } ``

Conclusion

結局typescriptとyarnはglobal installした。nodeのversion管理をvoltaで今後はしばらく行う。 yarnはv3だがpnpとzero install機能は使わないsetting node npm yarnの依存関係に悩まされてきたからスッキリした。 なんでもnpm installや -g でグローバルインストールしないのが成長に必要。

-save-dev saves the name and version of the package being installed in the dev-dependency object. As developers who are just getting started or want to build an application that can be easily deployed without any problem this difference is a must know.