# 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

```bash
# 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

```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

```json
{
  "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

```bash
# 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

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

### 8.3 Webpack

#### 8.3.1 Basic Configuration

```javascript
// 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

```javascript
// 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

```javascript
// 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

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

### 8.5 ESLint

#### 8.5.1 Configuration

```javascript
// .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

```javascript
// 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

```javascript
// 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

```javascript
// 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

```bash
# 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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://triyono.gitbook.io/tutorial/java-script/bab-8-package-management-dan-build-tools.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
