css는 웹 표준이 정해지지 않아 브라우저마다 지원하는 범위가 각 속성들마다 다르다.
vender prefix는 css 문법에만 국한되어 사용되는 용어는 아니며, 사전적 의미로는 css 속성, 자바스크립트 api들 중 프로덕션에 쓰일 경우 표준화된 다른 api들과 같이 쓰임으로 혼돈이 오는 것을 방지하기 위해 구문의 어두에 붙이는 기호법이다. 개발자가 이 prefix를 쓰기 싫다면, 해당 문법이 완벽하게 표준화될 때까지는 해당 기능을 사용하면 안된다.
css vendor prefix에 대해 이야기를 해보면, IE는 버전 10미만 까지는 user-select 속성을 지원하지 않기 떄문에 이 실험적인 속성을 IE 11버전 이상부터는 사용하고 싶다면, IE에서 사용해야 하는 css vendor prefix인 -moz-를 붙여 아래와 같이 사용해야 한다.
-moz-user-select: none;
mdn 문서를 보면 조금 더 잘 와닿는다.
문서에 따르면 -x- 기호 표시는 vendor-prefix이며
아래 그림에서 user-select의 경우 IE 10버전 이상부터는 -x- 표시와 함께 가능하다고 나와있다. 즉, IE 10 이상 부터는 -moz-user-select 표시와 함께 사용이 가능하다는 설명이다.
vendor prefix와 표준 문법이 함께 쓰이는 경우에는 헷갈릴 수 있어 다음과 같이 TCPSCHOOL.com에서 제공하는 예제 코드를 가져온다.
<style>
.button {
background: red; <!-- gradient 속성을 지원하지 않는 모든 브라우저를 위한 코드 -->
background: -webkit-linear-gradient(red, yellow); <!-- 크롬과 사파리 4.0 이상을 위한 코드 -->
background: -moz-linear-gradient(red, yellow); <!-- 파이어폭스 3.6 이상을 위한 코드 -->
background: -ms-linear-gradient(red, yellow); <!-- 익스플로러 10.0 이상을 위한 코드 -->
background: -o-linear-gradient(red, yellow); <!-- 오페라 10.0 이상을 위한 코드 -->
background: linear-gradient(red, yellow); <!-- CSS 표준 문법 코드 -->
}
</style>
즉, 위의 코드에서 linear-gradient 속성을 지원하는 곳에서만 적용하고 싶은 경우, 위와 같이 linear-gradient를 지원하지 않는 브라우저 또한 폴백 스타일을 제공하기 위해서 다음과 같이 한다.
1.background: red;를 제일 먼저 작성한 후,
2.vendor-prefix를 이용해 작성하고
3.제일 마지막에 CSS 표준 문법 코드를 작성해야 한다.
vendor-prefix를 코드를 작성하는 사람이 일일이 순서와 기호를 신경쓰며 적는 것은 매우 고되고 유지보수성에 좋지 않은 영향을 가져다줄 여지가 있다. 이를 해결하는 여러 방법 중 한 가지로 autoprefixer를 이용하는 것이다.
autoprefixer는 all, break, custom, media query range와 같은 속성들을 최대한 많은 브라우저가 지원할 수 있게끔 자동으로 폴리필 해주는 라이브러리다.
CRA(Create-React-App) 환경에서는 추가 설정 없이도 autoprefixer를 자동으로 사용한다. 웹팩을 이용해 수동으로 autoprefixer 기능을 제공하기 위해서는 설정 파일에서 postcss-loader를 사용해야 한다.
다른 사람이 이미 구성해 놓은 웹팩 설정을 사용하는 것에 익숙하다면, postcss-loader 설정에 대해 충분히 살펴보지 못했을 수 있다. 또한 누구한테 물어보기도 조금 애매한 부분이라는 점에 공감하는 사람이 많을 것 같다. 내 케이스는 아니지만 같이 프로젝트를 진행하는 팀이 조금 냉정한 분위기라면 문서 링크 하나 던져주고 이거 보세요
했을 수도..
웹팩에서 postcss-loader를 설정할 때는 두가지 방법이 있다. 참고로 아래 예제 코드들은 웹팩 문서에서 또한 확인할 수 있다.
설정 코드들에 많은 괄호들이 있어 가독성이 좋지 않으나, 다음처럼 생각해보자.
PostCSS는 스타일링 파일들을 JS 플러그인들을 이용해 린팅하거나, vendor prefix를 붙여주는 기능등을 해주는 역할을 한다.
즉, 앞서 살펴본 autoprefixer
는 PostCSS에서 사용하는 여러 플러그인 중 가장 범용적으로 사용되는 JS 플러그인이고, 아래와 같은 문법을 이용해 postcss-loader가 postCSS에서 사용될 플러그인들을 설정해준다.
[정리] 웹팩에서 postCSS 기능을 이용해 스타일링을 린팅, autoprefix 하려면 postcss-loader를 이용해 설정해야 한다. postcss-loader가 웹팩에서 postCSS를 사용할 수 있게 해준다. 우리는 이 설정을 webpack.config.js 에서 하거나 postcss-loader에서 사용할 수 있다.
위의 설명을 먼저 읽어두고 아래 코드를 마주하면 위화감이 조금 덜하지 않을까?
(postcss-preset-env, postcss-short는 postcss의 default plugin이 아니므로 패키지 매니저를 사용해 수동으로 설치해줘야 한다._)
먼저 webpack.config.js 내부에서 설정하는 경우를 살펴보자.
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env",
["postcss-short", { prefix: "x" }],
],
},
},
},
],
},
],
},
};
style-loader, css-loader와 다르게 postcss-loader의 경우 postcssOptions 키 값에 plugins를 키값으로 가지는 객체를 value로 매핑해주고 있다.
plugins의 배열 안에는 string, 혹은 배열이 들어갈 수 있는데, 각 플러그인 마다 디폴트 옵션이 있다. 추가 설정을 하지 않으려면 postcss-preset-env
와 같이 설정한다. autoprefixer는 postcss-preset-env
의 디폴트 옵션에 속한다.
postcss-short
플러그인의 경우에는 prefix
옵션을 설정하기 위해 객체를 배열안에 같이 포함했다.
postcss-preset-env의 세부 옵션은 문서에서 확인할 수 있다.
설정 파일을 다른 곳에 별도로 만들 수 있다.
이 방법을 사용할 경우, webpack.config.js가 조금 더 간소화 됨을 아래에서 확인할 수 있다.
// postcss.config.js
module.exports = {
plugins: [
// Plugins for PostCSS
["postcss-short", { prefix: "x" }],
"postcss-preset-env",
],
};
//webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader", "postcss-loader"],
},
],
},
};
commonJS 방식을 이용해 객체를 exports 했으나, 다음처럼 함수를 정의할 수도 있다.
module.exports = {
module: {
rules: [
{
test: /\.(css|sss)$/i,
loader: "postcss-loader",
options: {
postcssOptions: (loaderContext) => {
if (/\.sss$/.test(loaderContext.resourcePath)) {
return {
parser: "sugarss",
plugins: [
["postcss-short", { prefix: "x" }],
"postcss-preset-env",
],
};
}
return {
plugins: [
["postcss-short", { prefix: "x" }],
"postcss-preset-env",
],
};
},
},
},
],
},
};
module.exports = (api) => {
// `api.file` - path to the file
// `api.mode` - `mode` value of webpack, please read https://webpack.js.org/configuration/mode/
// `api.webpackLoaderContext` - loader context for complex use cases
// `api.env` - alias `api.mode` for compatibility with `postcss-cli`
// `api.options` - the `postcssOptions` options
if (/\.sss$/.test(api.file)) {
return {
// You can specify any options from https://postcss.org/api/#processoptions here
parser: "sugarss",
plugins: [
// Plugins for PostCSS
["postcss-short", { prefix: "x" }],
"postcss-preset-env",
],
};
}
return {
// You can specify any options from https://postcss.org/api/#processoptions here
plugins: [
// Plugins for PostCSS
["postcss-short", { prefix: "x" }],
"postcss-preset-env",
],
};
};
본 글이 postcss를 학습하는데 어려움을 겪는 사람들에게 도움이 되었으면 좋겠다.
reference
https://webpack.js.org/loaders/postcss-loader/#config
https://www.npmjs.com/package/postcss-loader
https://yamoo9.gitbook.io/webpack/webpack/webpack-loaders/postcss