웹 개발의 세계에서도 트리즈(TRIZ) 같은 고려사항들이 항상 존재한다. 테스트용 className 또는 id가 바로 그 예시 중 하나이다.
트리즈(TRIZ) 이론에 대해 들어보았는가?
- 비행기는 충분한 양력을 얻기 위해 바퀴가 필요하다.
- 하지만 비행기가 하늘을 날기 시작하면 바퀴는 저항의 원인이 된다.
이러한 모순을 갖는 문제점들 말이다.
웹 개발에서도 Cypress등 E2E 테스트를 위한 className은 개발 및 테스팅 단계
에서 필수적
이다.
그러나 프로덕션
환경에서는 이러한 className이 필요 없을 뿐더러, 때로는 예상치 못한 사이드 이펙트
를 가져올 수 있다.
이러한 className의 모순. 어떻게 해결할 수 있을까?
비행기가 이륙할 때 바퀴는 필수적이지만, 일단 하늘을 날게 되면 그 바퀴는 불필요한 저항이 된다. 이 문제를 해결하기 위해, 엔지니어들은 비행기 이륙 후 바퀴를 몸체 안으로 접어 저항을 최소화
하는 방식을 채택했다.
이러한 지혜를 빌려 Test className의 모순을 극복할 수 있다.
우리의 코드는 개발단계를 지나 배포단계(비행)에 진입
할 때, webpack이나 rollup과 같은 도구로 번들링
을 진행한다. 이 과정에서 className을 바퀴처럼 제거
하면 되지 않을까?
Webpack
은 이 문제를 효과적으로 해결한다. postcss
와 purgecss
를 사용하면 번들링 과정에서 원하는 className을 쉽게 제거할 수 있다.
먼저, 필요한 의존성 모듈들을 설치한다.
yarn add -dev postcss-loader postcss-purgecss
이후 웹팩 설정에 다음과 같이 수정한다.
// webpack.config.js
// ...
module.exports = {
// ...
module: {
rules: [
// ...기존 loader 설정
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
[
require('postcss-purgecss')({
content: ['./src/**/*.html', './src/**/*.js'],
defaultExtractor: (content) =>
content.match(/[\w-/:]+(?<!:)/g) || [],
blocklist: [/^test-/],
}),
],
],
},
},
},
],
},
],
},
plugins: [
// ...기존 plugins config
new PurgeCSSPlugin({
paths: glob.sync(`${path.join(__dirname, 'src')}/**/*`, { nodir: true }),
blocklist: [/^test-/],
}),
],
// ...
};
이러한 방식으로 번들링 시점에서 test- 접두사를 가진 className을 제거할 수 있다. 이러한 방식은 프로덕션 코드의 예상치 못한 sideEffect와 성능 최적화 및 Test className을 노출방지를 고려한다.
다만, 위의 방법은 의존성 모듈이 테스트용 className을 제거하기 위해 나온 것이 아니기에, 원치 않는 방향으로 동작하는 등의 문제가 발생하였다.
개념은 사실상 위에서 언급한 것들과 동일하다. 차이점은 조금 더 간편하다는 것..?
적용해보자!
yarn add -D babel-plugin-react-remove-properties
class Foo extends React.Component {
render() {
return (
<div className="bar" data-test="thisIsASelectorForSelenium">
Hello Wold!
</div>
);
}
}
class Foo extends React.Component {
render() {
return (
<div className="bar">
Hello Wold!
</div>
);
}
}
//.babelrc
{
env: {
production: {
plugins: [
[
'react-remove-properties',
{ properties: ['data-test', 'data-foo', /^test-/] },
],
],
},
},
};
이전의 방식처럼 원하는 정규표현식을 추가하는 것도 가능하다. 😆