Webpack을 공부 했습니다.

Hwangro Lee
11 min readMar 6, 2021

--

https://webpack.js.org/concepts/

웹팩은 자바스크립트를 위한 모듈 번들러이다. 웹팩은 애플리케이션을 처리 할 때 프로젝트에 필요한 모든 모듈을 매핑하고 하나 이상의 번들을 생성하는 종속성 그래프를 내부적으로 빌드합니다.

하나의 파일이 다른 파일에 의존 할 때마다 webpack은 이를 종속성으로 취급합니다. 이를 통해 웹팩은 이미지 또는 웹 글꼴과 같은 Asset 을 가져와 애플리케이션에 대한 종속성으로 제공 할 수 있습니다.

webpack은 애플리케이션을 처리 할 때 명령 줄 또는 구성 파일에 정의 된 모듈 목록에서 시작합니다. 이러한 진입 점에서 시작하여 웹팩은 애플리케이션에 필요한 모든 모듈을 포함하는 종속성 그래프를 재귀 적으로 빌드 한 다음 이러한 모든 모듈을 브라우저에서 로드 파일로 번들링합니다.

Grunt, Gulp 와 같은 Task runner와 많이 비교를 하고 있지만 태스크러너는 작업을 순차적으로 실행시키는 작업을 하는데 이 작업들 중에 자바스크립트 번들, 스타일 , 이미지들의 작업을 하기 때문에 Webpack 처럼 번들러로써의 작업도 할 수 있습니다.

mode

https://webpack.js.org/configuration/mode/

none | development | production

production일 경우 배포용에 맞게 최적화한다.

entry

https://webpack.js.org/configuration/entry-context/

웹팩이 내부 종속성 그래프 작성을 시작하는 데 사용해야하는 모듈을 나타냅니다. webpack은 진입 점이 의존하는 다른 모듈과 라이브러리를 알아냅니다.

파일 경로를 배열로 전달할 경우 여러 종속 파일을 함께 주입할 수 있습니다.

"entry": {
"index": ["index.js"]
}

파일 경로를 배열이 아닌 객체로 전달하여 상세한 속성을 지정할 수 있습니다.

"entry": {
"init": ["init.js"],
"index": {
// 현재 entry가 의존하는 entry 입니다. 이 entry를 로드하기 전에 로드합니다.
"dependOn": "init",
"import": ["index.js"]
}
}

Output

webpack이 생성 한 번들을 내보낼 위치와 이러한 파일의 이름을 지정하는 방법을 알려줍니다.

output: {
// 번들링된 결과물의 파일이름을 지정한다.
filename: 'js/[name].js',
//청크파일의 이름을 지정한다.
chunkFilename: "js/[name].[contenthash].chunks.js",
// 번들링된 파일의 경로를 지정한다.
path: path.resolve(__dirname, 'dist')
}

아웃풋 파일 이름에는 placeholder를 지정할 수 있다.

- [id] - Returns the chunk id.
- [path] - Returns the file path.
- [name] - Returns the file name.
- [ext] - Returns the extension. [ext] works for most available fields.
- [fullhash] - Returns the build hash. If any portion of the build changes, this changes as well.
- [chunkhash] - Returns an entry chunk-specific hash. Each entry defined in the configuration receives a hash of its own. If any portion of the entry changes, the hash will change as well. [chunkhash] is more granular than [fullhash] by definition.
- [contenthash] - Returns a hash generated based on content. It's the new default in production mode starting from webpack 5.
https://survivejs.com/webpack/optimizing/adding-hashes-to-filenames/

자세한 output에 대한 옵션들은 이곳에서 확인 가능합니다.

https://webpack.js.org/configuration/output/

Plugins

https://webpack.js.org/configuration/plugins/

번들링하는 과정에서 사용할 수 있는 부가기능입니다. 압축, 핫리로딩, 변수설정, 파일복사, ESLint 등 부가기능을 수행할 수 있다.

또한 로더가 할 수없는 다른 작업을 수행 할 목적으로도 사용됩니다.

BundleAnalyzerPlugin

번들 된 파일에 어떤 라이브러리가 있는지 뷰로 보여줍니다.

plugins: {
// server: 서버를 띄워서 보여준다.
// static: html파일로 생성한다.
// disabled: 비활성화 한다.
new BundleAnalyzerPlugin({
analyzerMode: 'server' | 'static' |'disabled'
})
}

ProvidePlugin

글로벌로 변수를 설정하기 위해 사용한다.

plugins: {
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
})
}

DefinePlugin

번들 중에 필요한 상수를 정의한다.

plugins: {
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env.NODE_ENV),
})
}

CircularDependencyPlugin

순환참조로 인해 발생하는 이슈를 확인하기 위해 사용한다.

plugins: {
new CircularDependencyPlugin({

// exclude detection of files based on a RegExp
exclude: /node_modules/,

// include specific files based on a RegExp
include: /src/,

// add errors to webpack instead of warnings
failOnError: true,

// allow import cycles that include an asyncronous import,
// e.g. via import(/* webpackMode: "weak" */ './file.js')
// allowAsyncCycles: false,
// set the current working directory for displaying module paths
// cwd: process.cwd(),
onStart({ compilation }) {
numCyclesDetected = 0;
},
onDetected({ module, paths, compilation }) {
numCyclesDetected++;
compilation.warnings.push(new Error(paths.join(' -> ')))
},
onEnd({ compilation }) {
if (numCyclesDetected > MAX_CYCLES) {
compilation.errors.push(new Error(`Detected ${numCyclesDetected} cycles which exceeds configured limit of ${MAX_CYCLES}`));
}
}
})
}

ESLintPlugin

https://www.npmjs.com/package/eslint-webpack-plugin

babel-eslint 가 deprecated 되고 eslint-webpack-plugin으로 새로 만들어졌다. babel-eslint는 module에서 사용했었다. 기본적으로 .eslintrc 를 참조한다.

plugins: {
new ESLintPlugin(
fix: !isProd,
exclude: ['node_modules'],
formatter: 'stylish'
})
}

CleanWebpackPlugin

https://www.npmjs.com/search?q=clean-webpack-plugin

빌드 폴더를 제거 / 정리하는 웹팩 플러그인.

plugins: {
new CleanWebpackPlugin({
})
}

MiniCssExtractPlugin

https://www.npmjs.com/package/mini-css-extract-plugin

CSS 파일로 만들고 싶을때 사용한다. 원래는 JS파일에 CSS파일이 임포트된다.

SpritesmithPlugin

아이콘, 이미지등을 하나의 파일로 만드는 sprite 작업을 한다.

function makeSprite ({ src, cssPrefix }) {
const suffix = src === 'assets' ? '' : `-${src}`,
imagePath = path.resolve(__dirname,`dist/sprites/sprites${suffix}.png`),
cssPath = path.resolve(__dirname, `dist/css/sprites${suffix}.css`),
cssSelector = ({ name }) => '.' + cssPrefix + '-' + name;

return new SpritesmithPlugin({
src: {
cwd: path.resolve(__dirname, `src/images/${src}`),
glob: '*.png'
},
target: {
image: imagePath,
css: [
[
cssPath, {
formatOpts: {
cssSelector: cssSelector,
},
}
]
]
},
spritesmithOptions: {
padding: 2,
algorithm: 'binary-tree'
},
apiOptions: {
cssImageRef: imagePath
},
retina: '@2x'
})
}

Loader

웹팩은 자바스크립트와 json만 이해할 수 있다. loader는 js, json외에 다른 파일을 웹팩이 이해할 수 있도록 변환해주는 작업을 한다. use 옵션은 오른쪽부터 왼쪽순으로 실행된다.

babel-loader

바벨을 통해 js파일을 번들링한다. 기본적으로 .babelrc 를 참조하여 번들링한다.

module: {
rules: [{
test: /\.js$$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader'
}
}]
}

css-loader

css를 불러온다 보통 스타일을 작성할때 css보다는 sass, less, postcss와 같은 문법을 사용하기 때문에 css-loader만 사용하지 않고 sass-loader, postcss-loader 를 함께 사용한다.

module: {
rules: [{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader, {
loader: 'css-loader',
options: {
esModule: false
}
}, {
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
/**
* .browserlistrc 를 통해 타겟 지정.
* babel도 .browserlistrc를 통해 번들링 한다.
* 지정한 타겟에도 호환이 되도록 css를 추가해준다.
*/
["autoprefixer"]
]
}
}
}, {
loader: 'sass-loader',
options: {
additionalData: "$host: 'localhost';"
}
}
]
}]
}

--

--