Bab 8: Package Management dan Build Tools

Bab 8: Package Management dan Build Tools

8.1 NPM (Node Package Manager)

8.1.1 Dasar NPM

# Inisialisasi proyek baru
npm init
npm init -y  # Skip questions with defaults

# Installing packages
npm install package-name
npm install package-name@version
npm install package-name --save-dev
npm install -g package-name

# Removing packages
npm uninstall package-name

# Updating packages
npm update
npm update package-name

# Running scripts
npm run script-name

8.1.2 Package.json

{
  "name": "my-project",
  "version": "1.0.0",
  "description": "Project description",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "build": "webpack --mode production",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "express": "^4.17.1",
    "react": "^17.0.2"
  },
  "devDependencies": {
    "webpack": "^5.65.0",
    "jest": "^27.4.5",
    "eslint": "^8.5.0"
  }
}

8.1.3 NPM Scripts

{
  "scripts": {
    "prebuild": "rimraf dist",
    "build": "webpack",
    "postbuild": "copyfiles -u 1 src/**/*.html dist",
    
    "dev": "npm-run-all --parallel watch:*",
    "watch:webpack": "webpack --watch",
    "watch:sass": "sass --watch src/styles:dist/styles",
    
    "test": "jest --coverage",
    "test:watch": "jest --watch"
  }
}

8.2 Yarn

8.2.1 Dasar Yarn

# Installing Yarn
npm install -g yarn

# Inisialisasi proyek
yarn init

# Installing packages
yarn add package-name
yarn add package-name@version
yarn add package-name --dev
yarn global add package-name

# Removing packages
yarn remove package-name

# Updating packages
yarn upgrade
yarn upgrade package-name

# Running scripts
yarn script-name

8.2.2 Yarn Workspaces

{
  "private": true,
  "workspaces": [
    "packages/*"
  ],
  "dependencies": {
    "shared-lib": "1.0.0"
  }
}

8.3 Webpack

8.3.1 Basic Configuration

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.[contenthash].js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                type: 'asset/resource'
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]
};

8.3.2 Development Configuration

// webpack.dev.js
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
    mode: 'development',
    devtool: 'inline-source-map',
    devServer: {
        contentBase: './dist',
        hot: true,
        port: 3000,
        historyApiFallback: true
    }
});

8.4 Babel

8.4.1 Configuration

// babel.config.js
module.exports = {
    presets: [
        ['@babel/preset-env', {
            targets: {
                node: 'current',
                browsers: ['> 1%', 'last 2 versions']
            }
        }],
        '@babel/preset-react'
    ],
    plugins: [
        '@babel/plugin-proposal-class-properties',
        '@babel/plugin-transform-runtime'
    ]
};

8.4.2 Integration with Webpack

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

8.5 ESLint

8.5.1 Configuration

// .eslintrc.js
module.exports = {
    env: {
        browser: true,
        es2021: true,
        node: true
    },
    extends: [
        'eslint:recommended',
        'plugin:react/recommended'
    ],
    parserOptions: {
        ecmaVersion: 12,
        sourceType: 'module'
    },
    rules: {
        'indent': ['error', 4],
        'linebreak-style': ['error', 'unix'],
        'quotes': ['error', 'single'],
        'semi': ['error', 'always']
    }
};

8.6 Development vs Production Builds

8.6.1 Production Configuration

// webpack.prod.js
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = merge(common, {
    mode: 'production',
    optimization: {
        minimizer: [
            new TerserPlugin(),
            new CssMinimizerPlugin()
        ],
        splitChunks: {
            chunks: 'all'
        }
    }
});

8.7 Module Bundlers

8.7.1 Rollup Configuration

// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
import { terser } from 'rollup-plugin-terser';

export default {
    input: 'src/main.js',
    output: {
        file: 'bundle.js',
        format: 'iife'
    },
    plugins: [
        resolve(),
        commonjs(),
        babel({
            exclude: 'node_modules/**'
        }),
        terser()
    ]
};

8.8 Task Runners

8.8.1 Gulp Configuration

// gulpfile.js
const { src, dest, watch, series, parallel } = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const autoprefixer = require('gulp-autoprefixer');
const cssnano = require('gulp-cssnano');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify');

function styles() {
    return src('src/styles/**/*.scss')
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(cssnano())
        .pipe(dest('dist/css'));
}

function scripts() {
    return src('src/js/**/*.js')
        .pipe(babel())
        .pipe(uglify())
        .pipe(dest('dist/js'));
}

exports.default = series(parallel(styles, scripts));
exports.watch = function() {
    watch('src/styles/**/*.scss', styles);
    watch('src/js/**/*.js', scripts);
};

8.9 Praktik dan Latihan

8.9.1 Project Setup

# Project initialization
mkdir my-project && cd my-project
npm init -y

# Installing dependencies
npm install webpack webpack-cli --save-dev
npm install babel-loader @babel/core @babel/preset-env --save-dev
npm install eslint --save-dev

# Creating configuration files
touch webpack.config.js
touch .babelrc
touch .eslintrc.js

8.10 Best Practices

  • Dependency management

  • Build optimization

  • Code splitting

  • Asset optimization

  • Caching strategies

8.11 Ringkasan

  • Package managers (NPM, Yarn)

  • Build tools (Webpack, Rollup)

  • Transpilers (Babel)

  • Linters (ESLint)

  • Task runners (Gulp)

8.12 Latihan Akhir Bab

  1. Setup complete development environment

  2. Configure production build process

  3. Implement code splitting

  4. Setup automated testing

  5. Create custom build scripts

Last updated