JS と CSS を HTML テンプレートで読み込んでという化石な環境で開発をしています。
前回は SCSS だけ webpack でビルドする環境を作りました。
今回は Vanilla JS でブラウザ対応を考えながら書くのは流石に DX が最悪なので最低限のトランスパイルできる環境を作成を作成しました。
環境設定は本当に分からんので間違いあればご指摘ください :pray:
環境
- webpack 5.60.0
- @babel/core 7.15.8
- typescript 4.4.4
Webpack + babel で JS を ES5 にトランスパイルできる環境を作る
# webpack $ npm i -D webpack webpack-cli # babel $ npm i -D @babel/core @babel/preset-env babel-loader babel-preset-minify # polyfill $ npm i core-js@3
Babel の設定
babel.config.js
module.exports = (api) => { const isProduction = api.env("production"); return { presets: [ [ "@babel/preset-env", { useBuiltIns: "usage", corejs: 3, }, ], [ "minify", // production mode の時に console.log を削除する isProduction && { removeConsole: { exclude: ["error", "info"], }, }, ].filter(Boolean), ], }; };
Webpack の設定
webpack.config.js
module.exports = (env, argv) => { const mode = argv.mode || process.env.NODE_ENV || "development"; if (!process.env.NODE_ENV) { process.env.NODE_ENV = mode } const enabledSourcemap = mode === "development"; const useCache = mode === "development"; return { mode, target: ["web", "es5"], cache: useCache, devtool: enabledSourcemap ? "inline-source-map" : false, entry: { "main": "src/index.js" }, output: { path: `${OUTPUT_DIR}`, filename: "[name].js", }, module: { rules: [ { test: /\.m?js$/, exclude: /node_modules/, use: ["babel-loader"], }, ], }, }; };
build コマンド
package.json
{ "scripts": { "build": "webpack --mode=production", "dev": "webpack --watch --progress" } }
TypeScript を babel でトランスパイルする
ts-loader
を使わなくても @babel/preset-typescript
を使えば babel で直接 TypeScript をトランスパイルできる。(ビルド時の型チェックはしてなさそうですが)
FAST! Because Babel only does code transforms, the build step becomes incredibly fast as it skips the type-checking step and just strips out the all the TypeScript type-annotations – converting it to vanilla JS.
cf. TypeScript -- @babel/preset-typescript & ts-loader
$ npm i -D typescript @babel/preset-typescript
TypeScript 設定
tsconfig.json
{ "compilerOptions": { "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], "module": "esnext", "moduleResolution": "node", "strict": true, "allowJs": true, // default export を許容 "allowSyntheticDefaultImports": true, // [...querySelectorAll()] の様な表記をエラーにしないう "downlevelIteration": true, // Enables experimental support for emitting type metadata for decorators which works with the module reflect-metadata. "emitDecoratorMetadata": true, // default import をエラーにしない (default import のヘルパーメソッドを生成する) "esModuleInterop": true, // デコレーターでエラーを表示しない "experimentalDecorators": true, // import 時にファイルの大文字小文字を区別する "forceConsistentCasingInFileNames": true, // 使用されてない変数をエラーにする "noUnusedLocals": true, // コンパイル結果を出力しない "noEmit": true, // 早期リターンを強要する (分岐条件内に return がないとエラー) "noImplicitReturns": true, // switch 内に break か return がないとエラー "noFallthroughCasesInSwitch": true, // JSON ファイルから型の抽出・生成ができるようにする "resolveJsonModule": true, // `*.d.ts` ファイツの方チェックを行わない (node_modules 内のライブラリの型定義ファイルの型チェックも行わない) "skipLibCheck": true }, "include": ["src/*"], "exclude": ["node_modules"] }
cf. tsconfig.jsonの全オプションを理解する(随時追加中) - Qiita
Babel, Webpack の設定を修正する
babel.config.js
return {
presets: [
[
"@babel/preset-env",
{
useBuiltIns: "usage",
corejs: 3,
},
],
+ "@babel/typescript",
[
"minify",
webpack.config.js
entry: { - "main": "src/index.js" + "main": "src/index.ts" }, // ... module: { rules: [ { - test: /\.m?js$/, + test: /\.(mjs|js|ts)$/, exclude: /node_modules/, use: ["babel-loader"], }, ], }, + resolve: { + extensions: [".ts", ".js"], + } };
npm run build
で .ts
ファイルもビルドできていれば OK
所管
昨今のフロントエンド開発だと React や Vue や Next や Nuxt でもビルド環境用意されているので、秘伝のタレを自分で作ることってなかなかなくなってる気がします。僕自身も webpack の設定から babel, tsconfig の設定を作るの久しぶりすぎて、その間に設定も色々変わってるし、環境づくりあまり面白くもないしなんもわからん…となりました。
もう react とか使える環境以外でフロントエンド書けない体になってしまった…
[参考]
- babel-loader | webpack
- 【webpack5】ts-loader + babel-loader を併用する【TypeScript】 - Qiita
tsconfig.jsonの全オプションを理解する(随時追加中) - Qiita
- TypeScript: Documentation - Decorators
- TypeScript の ES6 modules の解釈と allowSyntheticDefaultImports の整理 - Qiita
- Emit Decorator Metadata - emitDecoratorMetadata
- TypeScript の esModuleInterop フラグについて - 30歳からのプログラミング
- VSCodeのDecoratorに関するエラー:[ts] Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning. - 中安拓也のブログ
- Resolve JSON Module - resolveJsonModule
- Skip Lib Check - skipLibCheck
- tsconfigのmoduleとtargetには何を設定すればいいか - TypeScript - Qiita
- tscとBabel | みどりのさるのエンジニア
- 最新版TypeScript+webpack 5の環境構築まとめ(React, Vue.js, Three.jsのサンプル付き) - ICS MEDIA
- Babel7.x時代のpolyfillの設定方法とuseBuiltInsの仕組み
- @babel/preset-env · Babel