
모듈이란?
- 모듈이란 프로그래밍 관점에서 특정 기능을 갖는 작은 코드 단위를 의미합니다. 자바스크립트로 치면 아래와 같은 코드가 모듈입니다.이처럼 성격이 비슷한 기능들을 하나의 의미 있는 파일로 관리하면 모듈이 됩니다.
- 웹팩에서 지칭하는 모듈이라는 개념은 위와 같이 자바스크립트 모듈에만 국한되지 않고 웹 애플리케이션을 구성하는 모든 자원을 의미합니다. 웹 애플리케이션을 제작하려면 HTML, CSS, Javascript, Images, Font 등 많은 파일들이 필요하죠. 이 파일 하나하나가 모두 모듈입니다.
- 문제점은 실제로 복잡한 애플리케이션을 개발할 때 발생합니다. 변수의 이름을 모두 기억하지 않은 이상 변수를 중복 선언하거나 의도치 않은 값을 할당할 수 있다는 것이다. 이처럼 파일 단위의 자바스크립트 모듈 관리의 필요성은 번들러가 탄생의 요인(1)으로써 작용하게 되었다
- 파일단위의 자바스크립트 모듈은 어떤 변수가 해당 파일/모듈 안에서만 유효한 값이 되도록 한다
번들러란?
- 웹 어플리케이션에서 가장 느린 부분은 일반적으로 HTTP Request입니다. 어플리케이션이 html, css, js, 이미지등등의 파일들로 많이 나누어져도 로컬머신 내에서는 문제없이 처리하지만, 웹 상에서는 나누어진 수 많은 파일들을 요청과 응답으로 전달받기 때문에 시간이 오래걸리는 작업이다.
- 그러니 가능하면 파일을 나누어서 요청을 받기 보다는 하나로 합쳐서 보내는 것이 현명(2)할 것입니다. 하지만 개발자 입장에서 몇천 또는 몇만줄의 코드를 하나의 파일애 작성하고 관리를 해야 한다면 그건 저주와 같을 수 있습니다. 이런 고민을 해결해 줄 수 있는 것이 번들러입니다. 번들러는 지정한 단위로 파일들을 하나로 만들어서 요청에 대한 응답으로 전달할 수 있은 환경을 만들어주는 역할을 합니다
- 대표적인 번들러 : Webpack, Parcel, ...
웹팩이란?
- 대표적인 번들러로써, 하나의 자바스크립트 파일에 자바스크립트 뿐만 아니라 css, image와 같은 여러 모듈들을 모두 넣을 수 있고 필요시 다시 분리할 수 있다.
- 활반한 웹팩 생태계의 다양한 확장기능들 덕분에 많은 작업을 자동화 할 수 있다.
- 웹팩설치 : npm install -g webpack webpack-cli
- 웹팩실행커맨드 : npx webpack --entry [엔트리파일] --output-path [번들파일저장위치]
- webpack.config.js : 웹팩에게 수동으로 커맨드및 옵션들을 전달하지 않고 웹팩이 어떻게 번들링할지를 명시하는 파일
* webpack.config.js 예시
webpack.config.js 공식홈페이지 예시파일
const path = require('path');
module.exports = {
mode: "production", // "production" | "development" | "none"
// Chosen mode tells webpack to use its built-in optimizations accordingly.
entry: "./app/entry", // string | object | array
// defaults to ./src
// Here the application starts executing
// and webpack starts bundling
output: {
// options related to how webpack emits results
path:path.resolve(__dirname, "dist"), // string (default)
// the target directory for all output files
// must be an absolute path (use the Node.js path module)
filename: "[name].js", // string (default)
// the filename template for entry chunks
publicPath: "/assets/", // string
// the url to the output directory resolved relative to the HTML page
library: { // There is also an old syntax for this available (click to show)
type: "umd", // universal module definition
// the type of the exported library
name: "MyLibrary", // string | string[]
// the name of the exported library
/* Advanced output.library configuration (click to show) */
},
uniqueName: "my-application", // (defaults to package.json "name")
// unique name for this build to avoid conflicts with other builds in the same HTML
name: "my-config",
// name of the configuration, shown in output
/* Advanced output configuration (click to show) */
/* Expert output configuration 1 (on own risk) */
/* Expert output configuration 2 (on own risk) */
},
module: {
// configuration regarding modules
rules: [
// rules for modules (configure loaders, parser options, etc.)
{
// Conditions:
test: /\.jsx?$/,
include: [
path.resolve(__dirname, "app")
],
exclude: [
path.resolve(__dirname, "app/demo-files")
],
// these are matching conditions, each accepting a regular expression or string
// test and include have the same behavior, both must be matched
// exclude must not be matched (takes preferrence over test and include)
// Best practices:
// - Use RegExp only in test and for filename matching
// - Use arrays of absolute paths in include and exclude to match the full path
// - Try to avoid exclude and prefer include
// Each condition can also receive an object with "and", "or" or "not" properties
// which are an array of conditions.
issuer: /\.css$/,
issuer: path.resolve(__dirname, "app"),
issuer: { and: [ /\.css$/, path.resolve(__dirname, "app") ] },
issuer: { or: [ /\.css$/, path.resolve(__dirname, "app") ] },
issuer: { not: [ /\.css$/ ] },
issuer: [ /\.css$/, path.resolve(__dirname, "app") ], // like "or"
// conditions for the issuer (the origin of the import)
/* Advanced conditions (click to show) */
// Actions:
loader: "babel-loader",
// the loader which should be applied, it'll be resolved relative to the context
options: {
presets: ["es2015"]
},
// options for the loader
use: [
// apply multiple loaders and options instead
"htmllint-loader",
{
loader: "html-loader",
options: {
// ...
}
}
]
type: "javascript/auto",
// specifies the module type
/* Advanced actions (click to show) */
},
{
oneOf: [
// ... (rules)
]
// only use one of these nested rules
},
{
// ... (conditions)
rules: [
// ... (rules)
]
// use all of these nested rules (combine with conditions to be useful)
},
],
/* Advanced module configuration (click to show) */
},
resolve: {
// options for resolving module requests
// (does not apply to resolving of loaders)
modules: ["node_modules",path.resolve(__dirname, "app")],
// directories where to look for modules (in order)
extensions: [".js", ".json", ".jsx", ".css"],
// extensions that are used
alias: {
// a list of module name aliases
// aliases are imported relative to the current context
"module": "new-module",
// alias "module" -> "new-module" and "module/path/file" -> "new-module/path/file"
"only-module$": "new-module",
// alias "only-module" -> "new-module", but not "only-module/path/file" -> "new-module/path/file"
"module": path.resolve(__dirname, "app/third/module.js"),
// alias "module" -> "./app/third/module.js" and "module/file" results in error
"module": path.resolve(__dirname, "app/third"),
// alias "module" -> "./app/third" and "module/file" -> "./app/third/file"
[path.resolve(__dirname, "app/module.js")]: path.resolve(__dirname, "app/alternative-module.js"),
// alias "./app/module.js" -> "./app/alternative-module.js"
},
/* Alternative alias syntax (click to show) */
/* Advanced resolve configuration (click to show) */
/* Expert resolve configuration (click to show) */
},
performance: {
hints: "warning", // enum
maxAssetSize: 200000, // int (in bytes),
maxEntrypointSize: 400000, // int (in bytes)
assetFilter: function(assetFilename) {
// Function predicate that provides asset filenames
return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
}
},
devtool: "source-map", // enum
// enhance debugging by adding meta info for the browser devtools
// source-map most detailed at the expense of build speed.
context: __dirname, // string (absolute path!)
// the home directory for webpack
// the entry and module.rules.loader option
// is resolved relative to this directory
target: "web", // enum
// the environment in which the bundle should run
// changes chunk loading behavior, available external modules
// and generated code style
externals: ["react", /^@angular/],
// Don't follow/bundle these modules, but request them at runtime from the environment
externalsType: "var", // (defaults to output.library.type)
// Type of externals, when not specified inline in externals
externalsPresets: { /* ... */ },
// presets of externals
ignoreWarnings: [/warning/],
stats: "errors-only",
stats: {
// lets you precisely control what bundle information gets displayed
preset: "errors-only",
// A stats preset
/* Advanced global settings (click to show) */
env: true,
// include value of --env in the output
outputPath: true,
// include absolute output path in the output
publicPath: true,
// include public path in the output
assets: true,
// show list of assets in output
/* Advanced assets settings (click to show) */
entrypoints: true,
// show entrypoints list
chunkGroups: true,
// show named chunk group list
/* Advanced chunk group settings (click to show) */
chunks: true,
// show list of chunks in output
/* Advanced chunk group settings (click to show) */
modules: true,
// show list of modules in output
/* Advanced module settings (click to show) */
/* Expert module settings (click to show) */
/* Advanced optimization settings (click to show) */
children: true
// show stats for child compilations
logging: true,
// show logging in output
loggingDebug: /webpack/,
// show debug type logging for some loggers
loggingTrace: true,
// show stack traces for warnings and errors in logging output
warnings: true
// show warnings
errors: true,
// show errors
errorDetails: true,
// show details for errors
errorStack: true,
// show internal stack trace for errors
moduleTrace: true,
// show module trace for errors
// (why was causing module referenced)
builtAt: true,
// show timestamp in summary
errorsCount: true,
// show errors count in summary
warningsCount: true,
// show warnings count in summary
timings: true,
// show build timing in summary
version: true,
// show webpack version in summary
hash: true,
// show build hash in summary
},
devServer: {
proxy: { // proxy URLs to backend development server
'/api': 'http://localhost:3000'
},
contentBase: path.join(__dirname, 'public'), // boolean | string | array, static file location
compress: true, // enable gzip compression
historyApiFallback: true, // true for index.html upon 404, object for multiple paths
hot: true, // hot module replacement. Depends on HotModuleReplacementPlugin
https: false, // true for self-signed, object for cert authority
noInfo: true, // only errors & warns on hot reload
// ...
},
experiments: {
asyncWebAssembly: true,
// WebAssembly as async module (Proposal)
syncWebAssembly: true,
// WebAssembly as sync module (deprecated)
outputModule: true,
// Allow to output ESM
topLevelAwait: true,
// Allow to use await on module evaluation (Proposal)
}
plugins: [
// ...
],
// list of additional plugins
optimization: {
chunkIds: "size",
// method of generating ids for chunks
moduleIds: "size",
// method of generating ids for modules
mangleExports: "size",
// rename export names to shorter names
minimize: true,
// minimize the output files
minimizer: [new CssMinimizer(), "..."],
// minimizers to use for the output files
/* Advanced optimizations (click to show) */
splitChunks: {
cacheGroups: {
"my-name": {
// define groups of modules with specific
// caching behavior
test: /\.sass$/,
type: "css/mini-extract",
/* Advanced selectors (click to show) */
/* Advanced effects (click to show) */
}
},
fallbackCacheGroup: { /* Advanced (click to show) */ }
/* Advanced selectors (click to show) */
/* Advanced effects (click to show) */
/* Expert settings (click to show) */
}
},
/* Advanced configuration (click to show) */
/* Advanced caching configuration (click to show) */
/* Advanced build configuration (click to show) */
- webpack.config.js 로 webpack 실행 : npx webpack [--config webpack.config.js]
웹팩 모드
- 모드종류 : "production" | "development" | "none"
development | Sets process.env.NODE_ENV on DefinePlugin to value development. Enables useful names for modules and chunks. |
production | Sets process.env.NODE_ENV on DefinePlugin to value production. Enables deterministic mangled names for modules and chunks, FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin and TerserPlugin. |
none | Opts out of any default optimization options |
웹팩로더
- 자바스크립트파일 뿐만 아니라 css, .jpg등 다른 확장자 파일도 번들링하는 역활 수행
- 대표적인 로더 : css-loader(css파일을 불러옴), style-loader(불러온 css파일을 적용)
웹팩플러그인
- 번들링의 결과물을 원하는 형태로 변형하는 역활 수행
- 대표적인 플러그인 : HtmlWebPackPlugin (
'Frontend' 카테고리의 다른 글
var, let, const 차이 (0) | 2020.11.08 |
---|---|
JS 프로토타입 (0) | 2020.11.07 |
JS 클로저 (0) | 2020.11.07 |
JS this (0) | 2020.11.07 |
JS 실행 컨텍스트 (0) | 2020.11.07 |