LoginSignup
0
2

More than 3 years have passed since last update.

Webpackのcss loaderでcssファイルをstring型に変換、またはCSS Modules的に扱えるようにする。

Last updated at Posted at 2020-03-09

モチベーション

nodejs(typescript)でcssを以下のようにstring型で書いていたけど、.cssファイルで書いた方がVSCodeとかでcssの補完も効くよな。。と思い、実験してみました。

css.ts
const css = `
.description {
  overflow: hidden;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  color: #777;
  font-size: 12px;
  line-height: 19px;
  font-weight: 700;
  height: 57px;
}
`
hoge.ts
import css from './css';

const style = document.createElement('style');
style.textContent = css;

Webpackでできそう

色々と方法をググっていたら、webpackの公式ドキュメントで以下のような記述を発見。

(実装方法などは後述)

css-loader
toString
You can also use the css-loader results directly as a string, such as in Angular's component style.
css-loader | webpack

元々broserifyでjsなどbundleをしていましたが、ドキュメントの充実度とstackoverflowでの検索ヒット率でwebpackに乗り換えることを決意しました。

browserifyではbroserify-cssというモジュールでcssをトランスフォーム出来るそうです。(今回は試していません)

環境構築

ディレクトリ構成

root/
    ├ package.json
    ├ node_modules
    ├ tsconfig.json
    ├ webpack.config.js
    ├ sample.html
    ├ yarn.lock
    ├ src/
         ├ index.ts
         ├ css.css
         ├ css.text.css

package.jsonの設定

package.jsonに以下のmoduleを含める。

package.json
  "devDependencies": {
    "@types/node": "^12.11.6",
    "css-loader": "^3.4.2",
    "to-string-loader": "^1.1.6",
    "ts-loader": "^6.2.1",
    "typescript": "^3.6.4",
    "webpack": "^4.42.0",
    "webpack-cli": "^3.3.11"
  }

tsconfig.json

各自の設定で大丈夫かと思われます。

tsconfig.json
{
    "compilerOptions": {
        "noImplicitAny": false,
        "strict": true, 
        "target": "es5",
        "removeComments": true,    
        "rootDir": "./src/",
        "module": "es6",
        "sourceMap": false
    },
    "include": ["src"]
}

webpack.config.jsの設定

今回はmodule.rulesの中で、ファイルの末尾が.cssの場合はモジュールで読み込み、.text.cssのように.textがファイル名に入っている場合は、string形で読み込めるように設定。

webpack.config.js
const helpers = require('./webpack-helpers/helpers');

module.exports = {
  mode: 'production',
  entry: './src/index.ts',
  output: {
    path: __dirname,
    filename: 'bundle.js',
  },
  resolve: {
    extensions: ['.ts', '.js'],
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: 'ts-loader', //ts-loader使うよ
      },
      {
        test: /\.text\.css$/i,
        use: ['to-string-loader', 'css-loader'],
      },
      {
        test: /\.css$/i,
        exclude: /text/,
        use: [
          'style-loader', 
          {
            loader: 'css-loader',
            options: {
              modules: true,
            }
          }],
      },
    ],
  },
};

通常通りcssを書く。

css.text.css
#target1{
    width: 100px;
    height: 100px;
    background-color: red;
}
css.css
#target2{
    width: 100px;
    height: 100px;
    background-color: red; 
    opacity: 0.5;
}

cssをtsファイルの中で読み込み

typescirptファイル内で以下のようにcssをインポートすると、string型、またはCSS Modulesで扱えるようになる。

index.ts
const exec = (): void => {
  const cssText: string = require('./main.text.css').toString(); // string
  const styles = require('./main.css'); // CSS Modules
  const target1 = document.querySelector('#target1');
  const target2 = document.querySelector('#target2');

  if (target1) {
    target1.textContent = 'fuga';
    const style = document.createElement('style');
    style.textContent = cssText;
    document.body.appendChild(style);
  }

  if (target2) {
    const ptag = document.createElement('p');
    ptag.textContent = 'fugafuga';
    target2.appendChild(ptag);
    target2.id = styles.target2;
  }
};

exec();

注意点としては、cssをインポートする時はimportではなく、requireを使用しなければいけません。
(調査中なので追記をしたいと思います。)

sample.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="target1">
        hoge
    </div>
    <div id="target2">
        hogehoge
    </div>
    <script src="bundle.js"></script>
</body>
</html>

これでwebpackを実行すればファイルがbundleされて、以下のような表示になります。

スクリーンショット 2020-03-09 13.52.26.png

これでcssファイルで編集できるようになります。

以上。

0
2
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
2