Webpack의 css loader에서 css 파일을 string형으로 변환하거나 CSS Modules적으로 취급할 수 있도록 한다.

동기 부여



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에 다음 모듈을 포함시킵니다.

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
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를 임포트할 때는 .text 는 아니고, import 를 사용하지 않으면 안됩니다.
(조사 중이므로 추기를 하고 싶습니다.)

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>

이제 require 를 실행하면 파일이 bundle되어 다음과 같은 표시가 됩니다.



이제 css 파일에서 편집할 수 있습니다.

이상.

좋은 웹페이지 즐겨찾기