Webpack la gi

Sử dụng Webpack trong Angular 2    

  • Báo cáo

Bài đăng này đã không được cập nhật trong 4 năm

1. Webpack là gì ?

Webpack là một module bundler cho những ứng dụng javascript hiện đại. Bundle là quá trình gom (hay còn gọi là nén) các tài nguyên khác nhau (source code) vào một file duy nhất sau đó sẽ trả về client. Bundle có thể bao gồm javascript, css, html và hầu hết các loại file khác. Đồng thời, nó cũng có những ứng dụng khá tương đồng với các thư viện khác như: RequireJs, SystemJs,..Kết hợp với một số plugin nó có thể xử lý và nén các loại file như: Typescript, SASS, và LESS. Dưới đây là một số khái niệm quan trọng của Webpack.

1.1 Entry

Webpack tạo ra một đồ thị của toàn bộ những phụ thuộc trong ứng dụng của bạn. Điểm bắt đầu của đồ thị này được gọi là một entry. Entry nói cho Webpack nơi để bắt đầu và theo dõi các phụ thuộc để biết được cái gì cần bundle. Hoặc bạn có thể hiểu entry như file đầu tiên để khởi động app.

webpack.config.js

module.exports = {
  entry: './path/to/my/entry/app.js'
};

1.2 Output

Đây là nơi chỉ cho Webpack cần lưu trữ khi hoàn thành quá trình bundle

webpack.config.js

module.exports = {
  entry: './path/to/my/entry/app.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'output.bundle.js'
  }
};

1.3 Loaders

Loader in webpack chuyển đổi những file .css, .html, .jpg,.. đến những modules mà chúng được thêm trong đồ thị sự phụ thuộc. Chúng có 2 mục đích chính trong config:

  • Xác định những file nào nên được chuyển đổi bởi loader nào.
  • Chuyển đổi file đó để làm sao nó có thể thêm vào đồ thị sự phụ thuộc.

webpack.config.js

const config = {
  entry: './path/to/my/entry/app.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'output.bundle.js'
  },
  module: {
    rules: [
      {test: /\.(js|jsx)$/, use: 'babel-loader'}
    ]
  }
};

1.4 Plugins

Plusgins được sử dụng phổ biến nhất là để thực hiện bước cập nhật, biên tập các modules đã được bundle:

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins

const config = {
  entry: './path/to/my/entry/app.js',
  output: {
    filename: 'output.bundle.js',
    path: './dist'
  },
  module: {
    rules: [
      {test: /\.(js|jsx)$/, use: 'babel-loader'}
    ]
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin(),
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
};

module.exports = config;

2. Sử dụng Webpack trong Angular 2

- Configure Webpack

Tạo thư mục project mới

mkdir angular-webpack
cd    angular-webpack

Thêm một số file sau vào project:

package.json

{
  "name": "angular2-webpack",
  "version": "1.0.0",
  "description": "A webpack starter for Angular",
  "scripts": {
    "start": "webpack-dev-server --inline --progress --port 8080",
    "test": "karma start",
    "build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"
  },
  "license": "MIT",
  "dependencies": {
    "@angular/common": "~2.2.0",
    "@angular/compiler": "~2.2.0",
    "@angular/core": "~2.2.0",
    "@angular/forms": "~2.2.0",
    "@angular/http": "~2.2.0",
    "@angular/platform-browser": "~2.2.0",
    "@angular/platform-browser-dynamic": "~2.2.0",
    "@angular/router": "~3.2.0",
    "core-js": "^2.4.1",
    "rxjs": "5.0.0-beta.12",
    "zone.js": "^0.6.25"
  },
  "devDependencies": {
    "@types/node": "^6.0.45",
    "@types/jasmine": "^2.5.35",
    "angular2-template-loader": "^0.4.0",
    "awesome-typescript-loader": "^2.2.4",
    "css-loader": "^0.23.1",
    "extract-text-webpack-plugin": "^1.0.1",
    ...
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true
  }
}

webpack.config.js

module.exports = require('./config/webpack.dev.js');

config/helpers.js

var path = require('path');
var _root = path.resolve(__dirname, '..');
function root(args) {
  args = Array.prototype.slice.call(arguments, 0);
  return path.join.apply(path, [_root].concat(args));
}
exports.root = root;

config/webpack.common.js

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');

module.exports = {
  entry: {
    'polyfills': './src/polyfills.ts',
    'vendor': './src/vendor.ts',
    'app': './src/main.ts'
  },

  resolve: {
    extensions: ['', '.ts', '.js']
  },

  module: {
    loaders: [
      {
        test: /\.ts$/,
        loaders: ['awesome-typescript-loader', 'angular2-template-loader']
      },
      {
        test: /\.html$/,
        loader: 'html'
      },
      {
        test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
        loader: 'file?name=assets/[name].[hash].[ext]'
      },
      {
        test: /\.css$/,
        exclude: helpers.root('src', 'app'),
        loader: ExtractTextPlugin.extract('style', 'css?sourceMap')
      },
      {
        test: /\.css$/,
        include: helpers.root('src', 'app'),
        loader: 'raw'
      }
    ]
  },

  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: ['app', 'vendor', 'polyfills']
    }),

    new HtmlWebpackPlugin({
      template: 'src/index.html'
    })
  ]
};

- Các common configurations

entry: {
  'polyfills': './src/polyfills.ts',
  'vendor': './src/vendor.ts',
  'app': './src/main.ts'
},

Chúng ta đang chia ứng dụng tới 3 bundlers:

  • polyfills - các polyfills chuẩn chúng ta yêu cầu để chạy ứng dụng Angular trong hầu hết các trình duyệt hiện đại.
  • vendor - các files vendor chúng ta cần: Angular, lodash, bootstrap.css...
  • app - code ứng dụng.
resolve: {
  extensions: ['', '.ts', '.js']
},

Điều này nói cho webpack biết để resovle các files có extension match với biểu thức trên. Như vậy bạn có thể sử dụng

import { AppComponent } from './app.component.ts';

Hoặc

import { AppComponent } from './app.component';

Chỉ định loader:

module: {
  loaders: [
    {
      test: /\.ts$/,
      loaders: ['awesome-typescript-loader', 'angular2-template-loader']
    },
    {
      test: /\.html$/,
      loader: 'html'
    },
    {
      test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
      loader: 'file?name=assets/[name].[hash].[ext]'
    },
    {
      test: /\.css$/,
      exclude: helpers.root('src', 'app'),
      loader: ExtractTextPlugin.extract('style', 'css?sourceMap')
    },
    {
      test: /\.css$/,
      include: helpers.root('src', 'app'),
      loader: 'raw'
    }
  ]
},

  • awesome-typescript-loader - một loader để transpile code Typescript tới ES5.
  • angular2-template-loader - tải template của component và styles.
  • html - Cho template của component
  • images/fonts - Images và fonts cũng được bundle.
  • css - Cho css file

Thêm plugin

plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    name: ['app', 'vendor', 'polyfills']
  }),

  new HtmlWebpackPlugin({
    template: 'src/index.html'
  })
]

Ngoài ra còn một số config tôi không trình bày ở đây như: Environment, Test configuration.

- Tạo view, component

src/index.html



  
    
    Angular With Webpack
    
    
  
  
    Loading...
  

src/main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app/app.module';
if (process.env.ENV === 'production') {
  enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule);

src/app/app.component.ts

import { Component } from '@angular/core';
import '../../public/css/styles.css';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent { }

src/app/app.component.html

Hello from Angular App with Webpack

Webpack la gi

Các bạn có thể xem code đầy đủ tại link sau:

Angular2-webpack-demo

Điểm nổi bật:

Không có thẻ