코드를 입력하세요
package.json
의 "main": "index.js"
는 node 서버 개발 환경에서 사용하는 것이므로 무시해도 된다."react": "^16.13.1"
npm view <패키지명> versions
명령어를 통해 패키지의 모든 버전을 볼 수 있다.전역 함수 → 전역 스코프 오염
IIFE → 즉시 실행 함수 표현 (독립적인 스코프 생성됨)
var math = math || {}
;(function() {
function sum(a, b) {
return a + b
}
math.sum = sum
})()
CommonJS
exports function ~
문법 사용AMD (Asyncronous Module Definition)
UMD (Universal Module Definition)
→ 각자의 스펙을 제안하다가 ES2015에서 표준 모듈 시스템을 내 놓았다. 지금은 바벨과 웹팩을 이용해 모듈 시스템을 사용하는 것이 일반적이다.
ES2015
→ export function sum(a, b) { }
→ import * as math from './math.js';
강사님은 간단한 서버를 돌릴 때 lite-server
를 쓰신다. (npx lite-server
)
npm install -D webpack webpack-cli
node_modules/.bin/webpack --help
실습:
node_modules/.bin/webpack --mode development --entry ./src/app.js --output dist/main.js
// webpack.config.js
const path = require("path")
module.exports = {
mode: "development",
entry: {
main: "./src/app.js",
},
output: {
path: path.resolve("./dist"), // 절대 경로가 필요하면 다음과 같은 모듈 사용
filename: "[name].js", // entry가 여러 개일 경우 output 이름을 여러 개 만들려고 동적 지정
// 여기서는 main.js 생김 (entry의 main key와 매칭됨)
},
}
로더의 역할 : 웹팩은 모든 파일을 모듈로 바라본다. 스타일시트, 이미지, 폰트까지...
import
구문을 사용해서 자바스크립트 코드 안으로 가져올 수 있다.커스텀 로더 만들기
/**
* @param content test에 걸린 파일의 내용물
*/
module.exports = function myWebpackLoader(content) {
console.log("** 마이로더 동작")
return content
}
const path = require("path")
module.exports = {
mode: "development",
entry: {
main: "./src/app.js",
},
output: {
path: path.resolve("./dist"),
filename: "[name].js",
},
module: {
rules: [
{
test: /\.js$/, // 로더가 처리해야 할 파일의 패턴 (js확장자를 가진 모든 것)
use: [path.resolve("./my-webpack-loader.js")],
},
],
},
}
css-loader
npm install css-loader
style-loader
const path = require("path")
module.exports = {
mode: "development",
entry: {
main: "./src/app.js",
},
output: {
path: path.resolve("./dist"),
filename: "[name].js",
},
module: {
rules: [
{
test: /\.css$/, // 로더가 처리해야 할 파일의 패턴
use: ["style-loader", "css-loader"], // 해석 순서는 뒤에서부터 앞이다!! 주의
},
],
},
}
file-loader
{
test: /\.png$/,
loader: "file-loader",
options: {
publicPath: "./dist/", // 파일 로더가 처리하는 파일을 모듈로 사용했을 때 경로 앞에 추가되는 문자열
name: "[name].[ext]?[hash]", // 원본 파일명과 확장자, 해쉬 무력화를 위해 hash를 쿼리에 붙임
},
// use: ["file-loader"],
},
url-loader
{
test: /\.(png|jpe?g|gif|svg)$/,
loader: "url-loader",
options: {
publicPath: "./dist/",
name: "[name].[ext]?[hash]",
limit: 20000,
},
},
플러그인의 역할
커스텀 플러그인 만들기
class MyPlugin {
// 웹팩은 compiler라는 객체를 주입해 준다.
apply(compiler) {
compiler.hooks.done.tap("My Plugin", stats => {
console.log("MyPlugin: done")
})
}
}
module.exports = MyPlugin
그러면 어떻게 번들 결과에 접근할 수 있을까? 웹팩 내장 플러그인 BannerPlugin 코드를 참고하자.
const { compilation } = require("webpack")
class MyWebpackPlugin {
// 웹팩은 compiler라는 객체를 주입해 준다.
apply(compiler) {
// 플러그인이 종료되었을 때 실행
compiler.hooks.done.tap("My Plugin", stats => {
console.log("MyPlugin: done")
})
// 웹팩이 번들링한 결과물을 가져올 수 있다.
compiler.plugin("emit", (compilation, callback) => {
const source = compilation.assets["main.js"].source()
// console.log(source);
// 번들한 결과물에 내용을 추가
compilation.assets["main.js"].source = () => {
const banner = [
"/**",
" * 웹팩으로 빌드했습니다. ",
" * Built Date: " + new Date().toLocaleDateString(),
" */",
].join("\n")
return banner + "\n\n" + source
}
callback()
})
}
}
module.exports = MyWebpackPlugin
// 이렇게 하면 빌드 결과물 상단에 주석이 추가된다.
BannerPlugin
const webpack = require("webpack")
module.exports = {
// ...
plugins: [new webpack.BannerPlugin({ banner: "이것은 배너입니다." })],
}
DefinePlugin
const webpack = require("webpack")
module.exports = {
// ...
plugins: [
new webpack.DefinePlugin({}), // 빈 객체를 전달해도 기본적으로 넣어주는 값이 있다.
// process.env.NODE_ENV이다. 웹팩 설정의 mode에 설정한 값이 여기에 들어간다.
// development를 설정했기 때문에, 코드에서 process.env.NODE_ENV 변수로 접근하면
// "development" 값을 얻을 수 있다.
],
}
new webpack.DefinePlugin({
TWO: "1+1", // 1+1 이라는 코드 조각이 들어간다. eval같은거네?
THREE: JSON.stringify("1+1+1") // 문자열로 들어감
}),
HtmlTemplatePlugin
$ npm install -D html-webpack-plugin
이 플러그인으로 빌드하면 HTML파일로 아웃풋에 생성될 것이다. index.html → src/index.html로 옮긴 뒤 다음과 같이 작성.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>타이틀</title>
</head>
<body>
<!-- 로딩 스크립트 제거 -->
</body>
</html>
new HtmlWebpackPlugin({
template: "./src/index.html",
templateParameters: {
env: process.env.NODE_ENV === "development" ? " (개발)" : " (프로덕션)",
},
minify:
process.env.NODE_ENV === "production"
? {
collapseWhitespace: true,
removeComments: true,
}
: false,
}),
하고
$ NODE_ENV=development npm run build
로 환경변수 지정 후 실행하기
CleanWebpackPlugin
MiniCssExtractPlugin
{
test: /\.css$/, // 로더가 처리해야 할 파일의 패턴
use: [
process.env.NODE_ENV === "production" // 미니 css익스트랙트를 사용해야할땐 스타일로더 대신 자체 제공된 로더 씀
? MiniCssExtractPlugin.loader
: "style-loader",
"css-loader",
],
},
...
new CleanWebpackPlugin(),
...(process.env.NODE_ENV === "production"
? [new MiniCssExtractPlugin({ filename: "[name].css" })]
: []), // 얘는 로더 설정도 추가해야 한다.