0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

(メモ)TypeScriptで開発してブラウザ用モジュールに変換|圧縮する

0
Posted at

おおまかな流れ

TypeScript(.ts)で開発
commonjs(.cjs|.js)へパッケージング -> 公開.
commonjs(.cjs|.js) パッケージをECMAScript(.mjs|.js) -> Minimimize(*.min.js) -> 公開

みたいなことをする

おおまかな構成

  • TypeScript - 開発言語(本稿では v5)
    • tsc - .ts -> .cjs|.js に変換
       * tsconfig.json - VS Code 用の設定
       * tsconfig.build.json - .ts -> .cjs|.js 用の設定
       * tsconfig.build-type.json - .ts -> .d.ts 用の設定
  • browserify.cjs|.js -> .mjs|.js に変換
    • terser - Minimizer(最近はMinifyとも呼ぶらしい) .mjs|.js -> .min.js に変換

#0 事前設定

まずは以下

リンターとか

VSCode の設定とか

テスト自動化関連

本題

必要なパッケージ

#1 VSCode の設定

#1.1 tsconfig.json

コードエディタの設定

// [tsconfig.json]
{
  // VSCode 監視対象ディレクトリ
  "include": ["./src/**/*", "./test/**/*", "./.eslintrc"],
  
  // トランスパイラの設定
  "compilerOptions": {
    "target": "esnext",
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "esModuleInterop": true,
    "strict": true,
    "skipLibCheck": true,
    // "baseURL": ".", // typescript v7 からは除外
    "paths": {
      ...
    },
    ...
  }
}

#1.2 tsconfig.build.json

.ts -> .cjs|.js トランスパイル用の設定

// [tsconfig.build.json]
{
  // tsconfig を基底にする
  "extends": ["./tsconfig.json"],
  
  // 開発ソースのディレクトリ
  "include": ["./src/**/*"],
  
  // トランスパイルから除外するディレクトリ
  "exclude": ["./test/**/*", "node_modules", "**/node_modules"],

  // トランスパイラの設定枠
  "compilerOptions": {
    "baseUrl": ".", // typescript v7 からは こっちに入れる
    "noEmit": false,
    "rootDir": "./src", // 開発ソースのルートディレクトリ
    "outDir": "./dist", // 出力先
    "declaration": false, // 型の出力なし。別個に行う
    "removeComments": true // 出力結果からコメントは削除する
  }
}

#1.3 tsconfig.build-type.json

.ts -> .d.ts 型出力用の設定
基本は tsconfig.build.json と同じ

{
  // tsconfig を基底にする
  "extends": ["./tsconfig.json"],

  // 開発ソースのディレクトリ
  "include": ["./src/**/*"],
  
  // トランスパイルから除外するディレクトリ
  "exclude": ["./test/**/*", "node_modules", "**/node_modules"],

  // トランスパイラの設定枠
  "compilerOptions": {
    "baseUrl": ".", // typescript v7 からは こっちに入れる
    "noEmit": false,
    "rootDir": "./src", // 開発ソースのルートディレクトリ
    "outDir": "./dist", // 出力先
    "declaration": true, // 型を出力
    "declarationMap": true, // ソースマップの出力
    "declarationDir": "./dist", // 型ファイルの出力先
    "emitDeclarationOnly": true, // 型のみを出力
    "removeComments": false // JSDoc のコメントを残す。インラインコメントは削除される模様
  }
}

#1.4 terser.minify.json

terser の設定
.mjs|.js -> .min.js 用の設定
CLI パラメタでも指定可能

// [terser.minify.json]
{
  // 圧縮(Minimimize)の設定
  "compress": {
    "defaults": true // 圧縮の有効化
  },
  // 書式の設定
  "format": {
    "comments": "some" // 残す。tsc がどうせ消してしまう為、どちらでも可
  },
  // ソースマップの設定
  "sourceMap": {
    // .min.js に含める
    "content": "inline",
    "url": "inline"
  }
}

#2 commonjs (.cjs|js) ビルド

#2.1 先に型(.d.ts)をビルド

tsconfig.build-type.jsonを使う

# tsc-alias は import "@/hoge" -> "./hoge" に変換してくれるパッケージ
tsc -p ./tsconfig.build-type.json && tsc-alias -p ./tsconfig.build-type.json

↓ こんな感じに出力される

  • dist
    • sample.d.ts
    • sample.d.ts.map
// [./dist/sample.d.ts]
/**
 * JSDoc comments...
 * @param args arguments
 * @returns result
 */
export declare const sample: (args: any) => boolean;
//# sourceMappingURL=index.d.ts.map
// [./dist/sample.d.ts.map]
... 割愛 ...

#2.2 次に.cjs|.jsをビルド

tsconfig.build.jsonを使う

# tsc-alias は import "@/hoge" -> "./hoge" に変換してくれるパッケージ
tsc -p ./tsconfig.build.json && tsc-alias -p ./tsconfig.build.json

↓ こんな感じに出力される

  • dist
    • sample.js
// [sample.js]
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sample = void 0;
const lib_1 = __importDefault(require("./lib"));
const sample = (args) => {
    return lib_1.default.fn(args);
};
exports.sample = sample;

#3 ECMAScript (.mjs|.js)をビルド

  • commonjsとしてトランスパイルした ./dist/sample.jsをエントリポイントとして、引数として渡す
  • 出力先ディレクトリは ./public等、commonjsファイルとは別にする(混ぜても問題はないがファイル名の重複|上書きに注意

#3.1 browserify を実行 .cjs|.js -> .mjs|.js 変換

無圧縮

# ローカルインストールしている場合
node ./node_modules/browserify/bin/cmd.js ./dist/sample.js -o ./browser/bundle.js

↓ こんな感じに出力される

  • browser
    • bundle.js
// [./browser/bundle.js]
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sample = void 0;
const lib_1 = __importDefault(require("./lib"));
const sample = (args) => {
    return lib_1.default.fn(args);
};
exports.sample = sample;

},{"./lib":2}],2:[function(require,module,exports){
"use strict";
const lib = {
    fn: (args) => {
        return true;
    },
};
module.exports = lib;

},{}]},{},[1]);

#3.2 Minimimize (terser)する (.cjs|.js) -> .min.js に変換|圧縮

terser.minify.jsonを使う

# ローカルインストールしている場合
node ./node_modules/browserify/bin/cmd.js ./dist/sample.js --debug | terser --config-file ./terser.minify.json -o ./browser/bundle.min.js

ext. tscでトランスパイルする際、コメントを残したい

コメントを残したい場合 /*! で開始する
/*!で開始したコメントは残る
※ただし、関数内のインラインコメントは削除される等、完全ではない様子

// [sample.ts]

/*! 残したいコメント  */

/** 残らないコメント */

// 残らないコメント

/*! 残るコメント @licence MIT @autor (c) yyyy hoge */

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?