๐ ๋ณํ
๋๋ถ๋ถ์ ๋ฒ๋ค๋ฌ๋ค์ด ์ ์
๋ณํ(transform)์ ์ํ ํ๋ฌ๊ทธ์ธ ์ค์น์ ์ค์ (configuration)์ ์๊ตฌํฉ๋๋ค. Parcel ์ ๋ง์ ์์ ์ผ๋ฐ์ ์ธ ๋ณํ๊ณผ ํธ๋์คํ์ผ๋ฌ๋ฅผ ๋ด์ฅํ์ฌ ์ง์ํฉ๋๋ค. Babel์ ์ฌ์ฉํ๋ JavaScript, PostCSS์ ์ฌ์ฉํ๋ CSS, PostHTML์ ์ฌ์ฉํ๋ HTML ์ ๋ณํํ ์ ์์ต๋๋ค. Parcel ์ ๋ชจ๋ ์์์ ์ค์ ํ์ผ(์: .babelrc
, .postcssrc
)์ ๋ฐ๊ฒฌํ์ ๋ ์๋์ผ๋ก ์ด ๋ณํ์ ์คํํฉ๋๋ค.
์จ๋ํํฐ(third-party) node_modules
์์๋ ์๋ํฉ๋๋ค. ๋ง์ฝ ์ค์ ํ์ผ์ด ํจํค์ง์ ์ผ๋ถ๋ก ๋ง๋ค์ด์ง๋ฉด ๊ทธ ๋ณํ์ ํด๋น ๋ชจ๋์์๋ง ์๋์ผ๋ก ์ผ์ง๋๋ค. ์ด๊ฒ์ด ๋ฒ๋ค๋ง์ ๋น ๋ฅด๊ฒ ํด์ค๋๋ค. ์ค์ง ๋ณํ์ ํ์ํ ๋ชจ๋๋ง์ด ๊ฐ๊ณต๋๊ธฐ ๋๋ฌธ์
๋๋ค. ์ด๋ ๋ํ ์ด๋ค ํ์ผ์ ํฌํจํ๊ณ ์ ์ธํ๊ธฐ ์ํด ์๋์ผ๋ก ๋ณํ์ ๊ตฌ์ฑํ ํ์๊ฐ ์์์ ๋ปํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์
์ ์จ๋ํํฐ ์ฝ๋๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ๊ทธ๊ฒ์ด ์ด๋ป๊ฒ ๋น๋ ๋์๋์ง ์ ํ์๊ฐ ์์์ ์๋ฏธํฉ๋๋ค.
Babel
Babel์ ์ปค๋ค๋ ํ๋ฌ๊ทธ์ธ ํ๊ฒฝ์ ๊ฐ์ถ ์ธ๊ธฐ์๋ JavaScript ํธ๋์คํ์ผ๋ฌ์ ๋๋ค. Parcel ์ Babel ๊ณผ ํจ๊ป ์ฌ์ฉํ๋ ๊ฒ์ ๋ ๋ฆฝํ์ผ๋ก ์ฌ์ฉ ํ ๋๋ ๋ค๋ฅธ ๋ฒ๋ค๋ฌ์ ํจ๊ป ์ฌ์ฉํ ๋์ ๋๊ฐ์ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค.
ํ๋ฌ๊ทธ์ธ๊ณผ ํ๋ฆฌ์ ์ ์ฑ์ ์ค์น ํ์ธ์:
yarn add @babel/preset-env
๊ทธ๋ฆฌ๊ณ ๋์, .babelrc
๋ฅผ ๋ง๋ญ๋๋ค:
{
"presets": ["@babel/preset-env"]
}
PostCSS
PostCSS๋ plugin ์ ์ฌ์ฉํ์ฌ CSS ๋ฅผ ๋ณํํ๋ ๋๊ตฌ์
๋๋ค. autoprefixer, Preset Env, CSS Modules์ ๊ฐ์ด ๋ง์
๋๋ค. .postcssrc
(JSON), .postcssrc.js
, ๋๋ postcss.config.js
์ค ํ๋์ ํ์ผ์ ์์ฑํ์ฌ Parcel ๋ก PostCSS ๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
ํ๋ฌ๊ทธ์ธ์ ์ฑ์ ์ค์น ํ์ธ์:
yarn add postcss-modules autoprefixer
๊ทธ๋ฆฌ๊ณ .postcssrc
๋ฅผ ๋ง๋ญ๋๋ค:
{
"modules": true,
"plugins": {
"autoprefixer": {
"grid": true
}
}
}
ํ๋ฌ๊ทธ์ธ์ plugins
๊ฐ์ฒด์ ํค๋ก ์ง์ ๋๊ณ ์ต์
์ ๊ฐ์ฒด์ ๊ฐ์ผ๋ก ์ ์ ๋ฉ๋๋ค. ๋ง์ฝ ํ๋ฌ๊ทธ์ธ์ ์ต์
์ด ์๋ค๋ฉด, ๋์ true
๋ก ์ค์ ํ์ธ์.
Autoprefixer, cssnext ๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ๋๊ตฌ์ ๋์ ๋ธ๋ผ์ฐ์ ๋ .browserslistrc
๋ก ์ง์ ํ ์ ์์ต๋๋ค:
> 1%
last 2 versions
CSS Modules ์ ์ต์์ modules
ํค๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ๊ฐ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ํ์ฑํ ๋ฉ๋๋ค. CSS Modules ์ JavaScript ๋ฒ๋ค์ ํฌํจ๋ ๊ฐ์ฒด๋ฅผ ๋ด๋ณด๋ด๋ฏ๋ก Parcel ๋ก ํ์ฌ๊ธ ํน๋ณํ ์ง์์ ํ์๋ก ํ๊ธฐ ๋๋ฌธ์
๋๋ค. postcss-modules
๊ฐ ํ๋ก์ ํธ ์์ ์ค์น๋์ด์ผ ํจ์ ์ฃผ์ํ์ธ์.
CSS ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฐ์ด ์ฌ์ฉํ๊ธฐ
CSS ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๊ฐ์ด ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๊ทธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ .postcssrc
์์ CSS Module ์ ์ง์ํด์ผ ํฉ๋๋ค.
cssnano ์ฝ๋ ์ต์ํ ์ค์ ํ๊ธฐ
Parcel ์ ํ๋ก๋์
๋น๋๋ฅผ ํ ๋ cssnano๋ฅผ ์ถ๊ฐ๋ก ์ฌ์ฉํฉ๋๋ค. ๊ธฐ๋ณธ ์ค์ ์ ๋ณ๊ฒฝํ๊ณ ์ถ๋ค๋ฉด cssnano.config.js
ํ์ผ์ ์์ฑํด์ฃผ์ธ์.
module.exports = {
calc: false,
discardComments: {
removeAll: true
}
}
PostHTML
PostHTML ํ๋ฌ๊ทธ์ธ์ผ๋ก HTML ์ ๋ณํํ๊ธฐ ์ํ ๋๊ตฌ์
๋๋ค. .posthtmlrc
(JSON), .posthtmlrc.js
, posthtml.config.js
์ค ํ๋์ ํ์ผ์ ์์ฑํ์ฌ Parcel ์ PostHTML ์ ์ค์ ํ ์ ์์ต๋๋ค.
ํ๋ฌ๊ทธ์ธ์ ์ฑ์ ์ค์น ํ์ธ์.
yarn add posthtml-img-autosize
๊ทธ ํ, .posthtmlrc
์ ์์ฑํ์ธ์.
{
"plugins": {
"posthtml-img-autosize": {
"root": "./images"
}
}
}
ํ๋ฌ๊ทธ์ธ์ plugins
๊ฐ์ฒด์ ํค๋ก ์ง์ ๋๊ณ ์ต์
์ ๊ฐ์ฒด์ ๊ฐ์ผ๋ก ์ ์ ๋ฉ๋๋ค. ๋ง์ฝ ํ๋ฌ๊ทธ์ธ์ ์ต์
์ด ์๋ค๋ฉด, ๋์ true
๋ก ์ค์ ํ์ธ์.
TypeScript
TypeScript๋ ํ์ ์ด ์ถ๊ฐ๋ JavaScript ์ Superset ์ธ์ด๋ก, ์ปดํ์ผํ๋ฉด ์ผ๋ฐ JavaScript ๋ก ๋ณํ๋๋ฉฐ ์ต์ ES2015+ ๊ธฐ๋ฅ๋ค๋ ์ง์ํฉ๋๋ค. TypeScript ์ ๋ณํ ์์ ์ ์ถ๊ฐ์ ์ธ ์ค์ ์์ด ๊ฐ๋ฅํฉ๋๋ค.
<!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<script src="./index.ts"></script>
</body>
</html>
// index.ts
import message from './message'
console.log(message)
// message.ts
export default 'Hello, world'
ReasonML/BuckleScript
ReasonML์ BuckleScript๋ฅผ ์ด์ฉํด OCaml ์ JavaScript ๋ก ์ปดํ์ผํฉ๋๋ค. ์์กด์ฑ์ ์ค์นํ๊ณ bsconfig.json
์ ๋ง๋ค๋ฉด ReasonML ์ ์ฌ์ฉํ์ค ์ ์์ต๋๋ค.
$ yarn add bs-platform --dev
// bsconfig.json
// from https://github.com/BuckleScript/bucklescript/blob/master/jscomp/bsb/templates/basic-reason/bsconfig.json
{
"name": "whatever",
"sources": {
"dir": "src",
"subdirs": true
},
"package-specs": {
"module": "commonjs",
"in-source": true
},
"suffix": ".bs.js",
"bs-dependencies": [],
"warnings": {
"error": "+101"
},
"namespace": true,
"refmt": 3
}
<!-- index.html -->
<html>
<body>
<script src="./src/index.re"></script>
</body>
</html>
/* src/index.re */
print_endline("Hello World");
ReasonReact
ReasonReact๋ ReasonML ์ React ๋ฐ์ธ๋ฉ์ ๋๋ค. ์ญ์ Parcel ๊ณผ ํจ๊ป ์ด์ฉ ๊ฐ๋ฅํฉ๋๋ค.
$ yarn add react react-dom reason-react
// bsconfig.json
{
"name": "whatever",
+ "reason": {
+ "react-jsx": 2
+ },
"sources": {
"dir": "src",
"subdirs": true
},
"package-specs": {
"module": "commonjs",
"in-source": true
},
"suffix": ".bs.js",
"bs-dependencies": [
+ "reason-react"
],
"warnings": {
"error": "+101"
},
"namespace": true,
"refmt": 3
}
<!-- index.html -->
<html>
<body>
+ <div id="app"></div>
<script src="./src/index.re"></script>
</body>
</html>
/* src/Greeting.re */
let component = ReasonReact.statelessComponent("Greeting");
let make = (~name, _children) => {
...component,
render: _self => <div> (ReasonReact.string("Hello! " ++ name)) </div>,
};
/* src/index.re */
ReactDOMRe.renderToElementWithId(<Greeting name="Parcel" />, "app");
๋ฌธ์์ ๊ฐ์ ์ ๋์์ฃผ์ธ์
๋น ์ง์ ์ด ์๊ฑฐ๋ ๋ช ํํ์ง ์์ ๊ฒฝ์ฐ, ์น ์ฌ์ดํธ ์ ์ฅ์์ ์ด์๋ฅผ ์ ๊ธฐํด ์ฃผ์๊ฑฐ๋ ํ์ด์ง๋ฅผ ์์ ํด ์ฃผ์ธ์..