[webpack] javascript 라이브러리의 분리
https://minaminaworld.tistory.com/119 에서 선행되어서 이어지는 내용입니다.
문제 상황
- 자바스크립트 라이브러리와 main.js를 분리해야 되는 상황
- entry에서 분개를 한다.
1. 예를 들어서 외부라이러리 jquery , moment를 쓴다.
- 명령어 npm i jquery --save , npm i moment(시간 관련 라이브러리)
- 화면에 영향을 미치는 요소임으로 pakage.json에 dependencies 안에 기록이 된다.
- example.js 파일에서 jquery를 import 시켜준다.
- 그리고, 아래의 jquery를 이용해서 로그를 찍어준다.
// example.js
import "../css/reset.css";
import "../css/base.css";
import $ from "jquery"; // 추가
var moment = require('moment'); // 추가
function createDiv() {
var elem = document.createElement("div");
elem.innerHTML = "웹팩을 사용해보겠습니다";
return elem;
}
document.body.appendChild(createDiv());
$(function() { // html dom 완성시 실행되는 부분
console.log("jquery를 불러오는 것을 성공하였습니다");
});
2. webpack.config.js에서 entry 부분과 output.filename을 변경해준다.
var path = require("path");
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var MiniCssExtractPlugin = require("mini-css-extract-plugin");
var OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
var TerserJSPlugin = require("terser-webpack-plugin");
var ManifestPlugin = require("webpack-manifest-plugin");
module.exports = {
mode: "production", //배포용으로 변경, development 경우 제대로 압축이 안됨
// output을 두개로 나눠서 생성한다. 하나는 전체적인 import부분이 example.js
// libray는 외부의 라이브러리(node_modules에 설치한 라이브러리)
entry: { main: "./app/js/example.js", library: ["jquery" , "moment"] },
output: {
// output으로 배출한 js의 이름은 entry.key 값으로 생성된다.
filename: "[name].js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: "css-loader", options: { url: false, sourceMap: true } }
]
}
]
},
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})]
},
plugins: [
new MiniCssExtractPlugin({ filename: "style.css" }),
new ManifestPlugin({
fileName: "manifest.json",
basePath: "./dist/"
}) // 번들링한 모든 결과물을 확인이 가능함.
]
};
3. 빌드 - 성공 , 그러나 파일의 크기를 자세히 보자.
- example.js 코드는 16줄 밖에 안되는 library.js와 크기가 동일하다.
- 즉, main.js , library 안에도 moment,jquery 가 있는 경우,
- 중복으로 불러온 상황임으로 개선을 해야함.
-> 따로 분리되지 않은 상황
4. webpack.config.js에 optimization.splitChunks를 추가
var path = require("path");
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var MiniCssExtractPlugin = require("mini-css-extract-plugin");
var OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
var TerserJSPlugin = require("terser-webpack-plugin");
var ManifestPlugin = require("webpack-manifest-plugin");
module.exports = {
mode: "production", //배포용으로 변경, development 경우 제대로 압축이 안됨
// output을 두개로 나눠서 생성한다. 하나는 전체적인 import부분이 example.js
// libray는 외부의 라이브러리(node_modules에 설치한 라이브러리)
entry: { main: "./app/js/example.js", library: ["jquery" , "moment"] },
output: {
// output으로 배출한 js의 이름은 entry.key 값으로 생성된다.
filename: "[name].js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: "css-loader", options: { url: false, sourceMap: true } }
]
}
]
},
optimization: {
splitChunks: { //추가된 부분 main.js에서 라이브러리르 분리하는 작업
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: "library",
chunks: "all"
}
}
},
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})]
},
plugins: [
new MiniCssExtractPlugin({ filename: "style.css" }),
new ManifestPlugin({
fileName: "manifest.json",
basePath: "./dist/"
}) // 번들링한 모든 결과물을 확인이 가능함.
]
};
5. 빌드 - 성공 , main.js와 library.js 크기가 달라졌음을 확인
6. index.html에 libray.js와 main.js 파일로 각각 설정