はじめに
初めまして。最近昼夜逆転してきた yakiniku0220です。
今回は前回書いた記事の続編で、実際にVS Codeの拡張機能の開発でも採用しているTailwind CSSの導入に関して執筆しようと思いました。
前回の記事を読んでいない方はぜひ読んでいただけると幸いです。
VS CodeのセットアップやReact.jsの導入はこの記事では省きます。
Tailwind CSSのSetup
今回はTailwind CLIを使用した手順を記載します。
Tailwind CSSのInstall
まずはTailwind CSSをinstallしてtailwind.config.js
ファイルを生成します。
npm install -D tailwindcss
npx tailwindcss init
tailwind.config.jsにテンプレートファイルのパスを追記
先ほど生成したtailwind.config.js
にテンプレートファイルのパスを追記ます。
今回はdist配下のファイルをcontentに指定します。
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./dist/**/*.js"],
theme: {
extend: {},
},
plugins: [],
}
CSSにTailwindディレクティブを追加
今回はsrc配下にindex.css
というファイルを作成し、以下のコードを記載します。
@tailwind base;
@tailwind components;
@tailwind utilities;
Webpackの設定
対象のパッケージをinstallする
まずは以下のパッケージをinstallします。
yarn add -D css-minimizer-webpack-plugin mini-css-extract-plugin css-loader postcss-loader postcss autoprefixer
postcss.config.jsファイルを作成する
src配下にpostcss.config.js
ファイルを作成して以下のコードを追記します。
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
webpack.config.jsファイルを編集する
次にwebpack.config.js
ファイルに先ほどinstallしたpackageの設定を記載していきます。
//@ts-check
"use strict";
const path = require("path");
const webpack = require("webpack");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
//@ts-check
/** @typedef {import('webpack').Configuration} WebpackConfig **/
/** @type WebpackConfig */
const baseConfig = {
target: "node", // VS Code extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
mode: "none", // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
resolve: {
// support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
extensions: [".ts", ".js", ".tsx"],
},
plugins: [
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
}),
new MiniCssExtractPlugin({ // MiniCssExtractPluginを追記
filename: "./src/index.css",
}),
],
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: [
{
loader: "ts-loader",
},
],
},
{
test: /\.css$/i, // CSSファイルを別ファイルに抽出するために追加
use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"],
},
],
},
optimization: { // optimization.minimizerを追加
minimizer: [new CssMinimizerPlugin()],
},
devtool: "nosources-source-map",
infrastructureLogging: {
level: "log", // enables logging required for problem matchers
},
};
/** @type WebpackConfig */
const extensionConfig = {
...baseConfig,
entry: "./src/extension.ts", // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
output: {
// the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
path: path.resolve(__dirname, "dist"),
filename: "extension.js",
libraryTarget: "commonjs2",
},
externals: {
vscode: "commonjs vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
// modules added here also need to be added in the .vscodeignore file
},
};
/** @type WebpackConfig */
const webviewConfig = {
...baseConfig,
target: ["web", "es2020"],
entry: "./src/index.tsx",
experiments: { outputModule: true },
output: {
path: path.resolve(__dirname, "dist"),
filename: "webview.js",
libraryTarget: "module",
chunkFormat: "module",
},
};
/** @type WebpackConfig */
const styleConfig = { // index.cssをcompileするために処理を追加
...baseConfig,
entry: "./src/index.css",
output: {
path: path.resolve(__dirname, "dist"),
filename: "index.css",
},
};
module.exports = [extensionConfig, webviewConfig, styleConfig];
extension.tsファイルを編集する
最後にextension.ts
ファイルを編集します。
compileした際にdistディレクトリにindex.css
ファイルが生成されるので、React.jsを導入したときに作成したgetUri
関数を使用します。
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from "vscode";
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(
vscode.commands.registerCommand("react.start", () => {
// Create and show panel
const panel = vscode.window.createWebviewPanel(
"react",
"React Sample",
vscode.ViewColumn.One,
{
localResourceRoots: [
vscode.Uri.joinPath(context.extensionUri, "dist"),
],
enableScripts: true,
}
);
// And set its HTML content
panel.webview.html = getWebviewContent(
panel.webview,
context.extensionUri
);
})
);
}
// This method is called when your extension is deactivated
export function deactivate() {}
function getUri(
webview: vscode.Webview,
extensionUri: vscode.Uri,
pathList: string[]
) {
return webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, ...pathList));
}
function getNonce() {
let text = "";
const possible =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < 32; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
function getWebviewContent(webview: vscode.Webview, extensionUri: vscode.Uri) {
const webviewUri = getUri(webview, extensionUri, ["dist", "webview.js"]);
const styleUri = getUri(webview, extensionUri, ["dist", "src", "index.css"]);
const nonce = getNonce();
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cat Coding</title>
<link href="${styleUri}" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<script type="module" nonce="${nonce}" src="${webviewUri}"></script>
</body>
</html>`;
}
動作確認
index.tsx
ファイルにTailwind CSSを書いて確認してみます。
compile後、ちゃんとTailwind CSSが適用されているのが確認できました。
まとめ
今回VS Codeの拡張機能開発にTailwind CSSを入れてみました。
Tailwind CSSは個人開発でちょくちょく使っているので、個人的には開発体験は上がった気がします。
今回作ったサンプルコードは以下のリポジトリに作ってあります。
https://github.com/ebarakazuhiro/sample-vscode-extension
最後に
株式会社HRBrainでは新しいメンバーを募集中です。
興味がある方は下記のリンクから宜しくお願い致します。