[译]使用NPM和Webpack搭建Angular2工程

原创翻译,转载请注明出处。

原文标题:Angular2 with NPM and Webpack

原文地址:https://www.illucit.com/blog/2016/06/angular2-npm-webpack/

这篇文章演示了怎样使用Webpack来配置Angular2工程。这些配置还包含了TypeScript,Less,CSS(例如Bootstrap)和字体(例如FontAwesome)。

  • 必须的NPM包

Webpack需要的所有依赖,都放到package.json的devDependencies里,这样的话NPM就能自动安装它们。

package.json

{
  "version": "1.0.0",
  "name": "faces",
  "dependencies": {
    "@angular/common": "^2.0.0-rc.1",
    "@angular/compiler": "^2.0.0-rc.1",
    "@angular/core": "^2.0.0-rc.1",
    "@angular/http": "^2.0.0-rc.1",
    "@angular/router": "^2.0.0-rc.1",
    "@angular/platform-browser": "^2.0.0-rc.1",
    "@angular/platform-browser-dynamic": "^2.0.0-rc.1",
    "core-js": "2.2.2",
    "rxjs": "5.0.0-beta.6",
    "reflect-metadata": "0.1.3",
    "zone.js": "0.6.12"
    "jquery": "2.2.3",
    "bootstrap": "3.3.6",
    "font-awesome": "4.6.1"
  },
  "devDependencies": {
    "ts-loader": "0.8.2",
    "typescript": "1.8.10",
    "typings": "0.7.12",
    "webpack": "1.12.15",
    "es6-promise": "3.1.2",
    "es6-shim": "0.35.0",
    "extract-text-webpack-plugin": "1.0.1",
    "file-loader": "0.8.5",
    "gulp": "3.9.1",
    "less": "^2.6.1",
    "less-loader": "2.2.3",
    "style-loader": "0.13.1",
    "url-loader": "0.5.7",
    "webpack-merge": "0.8.4",
    "webpack-stream": "3.1.0"
  }
}

用NPM把所有的开发依赖包都安装完之后,我们就开始配置Webpack。

  • 配置Webpack

webpack.config.js

var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require("extract-text-webpack-plugin");

// Webpack Config
var webpackConfig = {
  entry: {
	'polyfills':       './wwwroot/polyfills.ts',
	'vendor':          './wwwroot/vendor.ts',
	'app':             './wwwroot/app.ts',
	'vendor-style':    './wwwroot/style/vendor-style.ts',
	'app-style':       './wwwroot/style/app-style.ts',
  },

  devtool: 'source-map',
  
  cache: true,
  output: {
	path: './wwwroot/dist',
	filename: '[name].bundle.js',
	sourceMapFilename: '[name].map',
	chunkFilename: '[id].chunk.js'
  },

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

  plugins: [
 
	new webpack.optimize.CommonsChunkPlugin({ name: ['app', 'vendor', 'polyfills'], minChunks: Infinity }),
	new ExtractTextPlugin("[name].css"),
	new webpack.optimize.DedupePlugin()
  ],

  module: {
	loaders: [
	  // .ts files for TypeScript
		{ test: /\.ts$/, loader: 'ts-loader' },
		{
			test: /\.css$/,
			loader: ExtractTextPlugin.extract("style-loader", "css-loader")
		},
		{
			test: /\.less$/,
			loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")
		},
		{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file" },
		{ test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader:"url?prefix=font/&limit=5000" },
		{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream" },
		{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml" }
	]
  }

};

var webpackMerge = require('webpack-merge');
module.exports = webpackMerge(webpackConfig);

 对这个配置文件的一些说明。在我的这个Angular2程序里,打包所有的文件需要大约30秒。如果在你每次修改文件之后都需要等20几秒也是挺浪费时间的。另外,所有下面的这些配置文件都需要放在Angular2工程的根目录下。

  

  • 分割工程

一个较好的方法,是把工程分割成polyfills文件,vendor文件和application自身文件。这种方式,在你每次修改都需要打包的时候,会节省不少时间。所以Webpack配置文件里包含了下面的命令:

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

Webpack会为每一个entry文件创建一个依赖图。已经包含在polyfills里的依赖将不会被再次放入vendor文件里。同样,已经包含在vendor和polyfills里的依赖将不会被加到app文件里。

polyfills和vendor文件是什么样子的呢:

polyfills.ts 

import 'core-js';
import 'zone.js/dist/zone';

vendor.ts 

import "@angular/common";
import "@angular/compiler";
import "@angular/core";
import "@angular/http";
import "@angular/router";
import "@angular/platform-browser";
import "@angular/platform-browser-dynamic";

import 'rxjs/Rx';

  

为了能然Webpack能编译TypeScript文件,你需要引入一个特殊的loader去复制.ts文件。下面的Webpack设定文件的loader部分的设定会达到这个目的。

{ test: /\.ts$/, loader: 'ts-loader' },

 这些loader是包含在package.json文件的devDependencies部分的npm包列表里。

  

  • 支持Less和CSS

配置文件里还包含了一些less和css的loader,例如:

{
   test: /\.css$/,
   loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
{
   test: /\.less$/,
   loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")
},

 为了把less或者css文件里使用的字体文件也打包,我还增加了一些loader,例如:

{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file" },

 这些包含了一些针对于字体文件的正则表达式。例如bootstrap里的字体文件。

 除了loaders之外,我还加了vendor styles 和app styles两个enter点。

vendor-style.ts 

import 'bootstrap/dist/css/bootstrap.css';
import 'font-awesome/less/font-awesome.less';

 

app-style.ts 

import './app.less';

 

  • 配置TypeScript

为了完整起见,我把tsconfig.json也贴出来。

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "outDir": ".",
    "rootDir": ".",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "moduleResolution": "node"
  },
  "exclude": [
    "typings/main.d.ts",
    "typings/main",
    "node_modules"
  ],
  "compileOnSave": false,
  "buildOnSave": false,
  "atom": { "rewriteTsconfig": false }
}

 

  • 配置Typings

Typings继承与tsd。它用来取得用纯javascript写成的库定义文件。你可以用typings命令行工具来为增加的库引入不同的typing定义。

typings.json

{
  "name": "myapp",
  "dependencies": {
  },
  "ambientDependencies": {
    "es6-collections": "registry:dt/es6-collections#0.5.1+20160215162030",
    "es6-promise": "registry:dt/es6-promise#0.0.0+20160221190517",
    "jquery": "registry:dt/jquery#1.10.0+20160316155526"
  }
}
  • 使用Webpack打包

首先使用npm安装webpack。之后你可以输入下面的命令开始打包。

webpack -d

它将在开发模式下编译出几个包。它还包含所有输出文件的map文件。这样的话,代码就可以在浏览器里被调试。如果你使用产品模式(在命令行里使用参数 -p),输出文件的大小将变小,并且不包含map文件。

Output:


 

 

bundles,font等等文件,都将被输出到在Webpack配置文件里定义的目标文件夹。

你可能注意到编译花费了不少时间。那为什么我们在最初把输出文件分成几块?因为我们可以使用监视模式来启动Webpack。

webpack -d -w

最初它会打包所有的文件。当所有的编译都完了之后,Webpack仍然会以监视模式运行。当你的程序文件被修改的时候,所有被影响的部分都会被重新编译。因为我们把代码分成了polyfills, vendor files和app本身几块,所以大多数情况之后app块被编译了。这样的话能稍微节省点时间。所以在开发阶段,我建议使用监视模式。

  •  在Html页面里使用输出文件

输出块被简单的包含在你的html页面里。就像下面所示:

<html>
<head>
    <title>MyApp</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0" />
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <link rel="stylesheet" href="dist/vendor-style.css" />
    <link rel="stylesheet" href="dist/app-style.css" />
</head>
 <body>
    
    <myapp>
      Loading...
    </myapp>

    <script src="dist/polyfills.bundle.js"></script>
    <script src="dist/vendor.bundle.js"></script>
    <script async src="dist/app.bundle.js"></script>

  </body>
</html>

 webkack还可以使用插件,这样的话你就不用手动在你的html页面里加入输出块文件。

  • 关于输出文件大小的附注

 在我的例子里,输出文件的大小仍然比较大,开发模式有4M,产品模式下有1M。不管怎样,这些文件最初被加载之后,你的单页应用也不在需要别的依赖了。如果有人告诉我怎样去再缩小输出文件的大小,那将非常棒!

  • 总结

 这篇文章演示了怎样去打包一个Angular2工程。在把各个方面综合在一起的时候,花费了我一些时间。希望大家在配置Angular2工程的时候,可以节省你的时间。如果有任何问题或者评论,可以在下面提交评论。

(译者注:去原页面评论哦~)

--End--

猜你喜欢

转载自stef.iteye.com/blog/2360428