anchor.diff:  .l-main-section
   :marked
     ### Loaders
  +
  +  ### 加载器(Loader)
   
     Webpack can bundle any kind of file: JavaScript, TypeScript, CSS, SASS, LESS, images, html, fonts, whatever.
     Webpack itself doesn't know what to do with a non-JavaScript file.
  -  We teach it to process such files into JavaScript with *loaders*. 
  +  We teach it to process such files into JavaScript with *loaders*.
     Here we configure loaders for TypeScript and CSS:
  -  
  +
  +  Webpack可以打包任何类型的文件：JavaScript、TypeScript、CSS、SASS、LESS、图片、HTML以及字体文件等等。
  +  Webpack本身并不知道该如何处理这些非JavaScript文件。
  +  我们要通过*加载器*来教它如何把这些文件处理成JavaScript文件。
  +  这里我们为TypeScript和CSS文件配置了加载器。
  +
   +makeExample('webpack/ts-snippets/webpack.config.snippets.ts', 'loaders', 'webpack.config.js (two entries)')(format=".")
   
   :marked
     As Webpack encounters `import` statements like these ...
  -  
  +
  +  当Webpack遇到像这样的`import`语句时……
  +
   +makeExample('webpack/ts-snippets/webpack.config.snippets.ts', 'imports')(format=".")
   
   :marked
  -  ... it applies the `test` RegEx patterns. When a pattern matches the filename, Webpack processes the file with the associated loader. 
  -  
  +  ... it applies the `test` RegEx patterns. When a pattern matches the filename, Webpack processes the file with the associated loader.
  +
  +  ……它会使用`test`正则表达式进行模式匹配。如果一个模式匹配上文件名，Webpack就用它所关联的加载器处理这个文件。
  +
     The first `import` file matches the `.ts` pattern so Webpack processes it with the `ts` (TypeScript) loader.
  -  The imported file doesn't match the second pattern so its loader is ignored. 
  -  
  -  The second `import` matches the second `.css` pattern for which we have *two* loaders chained by the (!) character. 
  -  Webpack applies chained loaders *right to left* so it applies 
  +  The imported file doesn't match the second pattern so its loader is ignored.
  +
  +  第一个`import`文件匹配上了`.ts`模式，于是Webpack就用`ts`(TypeScript)加载器处理它。
  +  导入的文件没有匹配上第二个模式，于是它的加载器就被忽略了。
  +
  +  The second `import` matches the second `.css` pattern for which we have *two* loaders chained by the (!) character.
  +  Webpack applies chained loaders *right to left* so it applies
     the `css` loader first (to flatten CSS `@import` and `url(...)` statements) and
      then the `style` loader (to append the css inside *&lt;style&gt;* elements on the page).
  -  
  +
  +  第二个`import`匹配上了第二个`.css`模式，在它上面我们有两个用(!)字符串联起来的加载器。
  +  Webpack会*从右到左*逐个应用串联的加载器，于是它先应用了`css`加载器(用来平面化`@import`和`url(...)`语句)，
  +  然后应用了`style`加载器(用来把css追加到页面上的*&lt;style&gt;*元素中)。
  +
   a(id="plugins")
   .l-main-section
   :marked
     ### Plugins
  -  
  +
  +  ### 插件
  +
     Webpack has a build pipeline with well-defined phases.
     We tap into that pipeline with plugins such as the `uglify` minification plugin:
  -  
  +
  +  Webpack有一条划分成多个良好定义的阶段(phase)的构建流水线。
  +  我们可以把插件（比如`uglify`代码最小化插件）挂到流水线上：
  +
   +makeExample('webpack/ts-snippets/webpack.config.snippets.ts', 'plugins')(format=".")
  -  
  +
   a(id="configure-webpack")
   .l-main-section
   :marked
     ## Configure Webpack
  -  
  -  After that brief orientation, we are ready to build our own Webpack configuration for Angular 2 apps. 
  -  
  +  ## 配置Webpack
  +
  +  After that brief orientation, we are ready to build our own Webpack configuration for Angular 2 apps.
  +
  +  在简短的培训之后，我们准备为Angular 2应用构建一份自己的Webpack配置了。
  +
     Begin by setting up the development environment.
  -  
  +
  +  从设置开发环境开始。
  +
     Create a **new project folder**
  +
  +  创建一个**新的项目文件夹**
  +
   code-example(format="").
     mkdir angular2-webpack
     cd    angular2-webpack
   
   :marked
     Add these files to the root directory:
  -  
  +
  +  把下列文件添加到根目录下：
  +
   +makeTabs(
     `webpack/ts/package.webpack.json,
     webpack/ts/typings.1.json,
  
positive.code: .l-sub-section
    :marked
      Many of these files and much of their content should be familiar from other Angular 2 documentation chapters.
      
      Learn about the `package.json` in the [npm packages](../guide/npm-packages.html) chapter.
      We require packages for Webpack use in addition to the ones listed in that chapter.
      
      Learn about `tsconfig.json` and `typings.json` in the [Typescript configuration](../guide/typescript-configuration.html) chapter.
  :marked
    Open a terminal/console window and install the *npm* packages with `npm install`.
   
    
  a(id="common-configuration")
  .l-main-section
  :marked
    ### Common Configuration
    
    We will define separate configurations for development, production, and test environments.
    All three have some configuration in common.
    We'll gather that common configuration in a separate file called `webpack.common.js`.
    
    Let's see the entire file and then walk through it a section at a time:
    
  +makeExample('webpack/ts/config/webpack.common.js', null, 'config/webpack.common.js')(format=".")
  
  :marked
    Webpack is a NodeJS-based tool so its configuration is a JavaScript _commonjs_ module file 
    that begins with `require` statements as such files do. 
    
    The configuration exports several objects, beginning with the *entries* described earlier:
    
  +makeExample('webpack/ts/config/webpack.common.js', 'entries', 'config/webpack.common.js')(format=".")
  :marked
    We are splitting our application into three bundles:
    
    * polyfills - the standard polyfills we require to run Angular 2 applications in most modern browsers.
    * vendor - the vendor files we need: Angular 2, lodash, bootstrap.css...
    * app - our application code.
    
  .callout.is-critical
    header Loading polyfills
    :marked
      Load Zone.js early, immediately after the other ES6 and metadata shims.
    
  :marked
    Our app will `import` dozens if not hundreds of JavaScript and TypeScript files. 
    We _might_ write `import` statements with explicit extensions as in this example:
  +makeExample('webpack/ts-snippets/webpack.config.snippets.ts', 'single-import')(format=".")
  
  :marked
    But most of our `import` statements won't mention the extension at all.
    So we  tell Webpack to _resolve_ module file requests by looking for matching files with
    
    * an explicit extention (signified by the empty extension string, `''`) or 
    * `.js` extension (for regular JavaScript files and pre-compiled TypeScript files) or 
    * `.ts` extension.
    
  +makeExample('webpack/ts/config/webpack.common.js', 'resolve', 'config/webpack.common.js')(format=".")
  .l-sub-section
    :marked
      We could add  `.css` and `.html` later if we want Webpack to resolve extension-less files with _those_ extension too.
  :marked
    Next we specify the loaders:
    
  +makeExample('webpack/ts/config/webpack.common.js', 'loaders', 'config/webpack.common.js')(format=".")
  
  :marked
    * ts - a loader to transpile our Typescript code to ES5, guided by the `tsconfig.json` file
    * html - for component templates
    * images/fonts - Images and fonts are bundled as well.
    * css - The pattern matches application-wide styles; the second handles component-scoped styles (the ones specified in a component's `styleUrls` metadata property).
  .l-sub-section
    :marked
      The first pattern excludes `.css` files within the `/src/app` directories where our component-scoped styles sit.
      It includes only `.css` files located at or above `/src`; these are the application-wide styles.
      The `ExtractTextPlugin` (described below) applies the `style` and `css` loaders to these files.
      
      The second pattern filters for component-scoped styles and loads them as strings via the `raw` loader &mdash;
      which is what Angular expects to do with styles specified in a `styleUrls` metadata property.
  
  :marked
    Finally we add two plugins:
    
  +makeExample('webpack/ts/config/webpack.common.js', 'plugins', 'config/webpack.common.js')(format=".")
  
  a(id="commons-chunk-plugin")
  :marked
    #### *CommonsChunkPlugin*
    
    We want the `app.js` bundle to contain only app code and the `vendor.js` bundle to contain only the vendor code. 
    
    Our application code `imports` vendor code. Webpack is not smart enough to keep the vendor code out of the `app.js` bundle.
    We rely on the `CommonsChunkPlugin` to do that job. 
  .l-sub-section
    :marked
      It identifies the hierarchy among three _chunks_: `app` -> `vendor` -> `polyfills`. 
      Where Webpack finds that `app` has shared dependencies with `vendor`, it removes them from `app`.
      It would do the same if `vendor` and `polyfills` had shared dependencies (which they don't).
  
  a(id="html-webpack-plugin")
  :marked
    #### *HtmlWebpackPlugin*
    
    Webpack generates a number of js and css files. 
    We _could_ insert them into our `index.html` _manually_. That would be tedious and error-prone.
    Webpack can inject those scripts and links for us with the `HtmlWebpackPlugin`.
    
  a(id="environment-configuration")
  .l-main-section
  :marked
    ### Environment-specific configuration
    
    The `webpack.common.js` configuration file does most of the heavy lifting. 
    We create separate, environment-specific configuration files that build on `webpack.common`
    by merging into it the peculiarities particular to their target environments.
    
    These files tend to be short and simple.
    
  a(id="development-configuration")
  .l-main-section
  :marked
    ### Development Configuration
    
    Here is the development configuration file, `webpack.dev.js`
    
  +makeExample('webpack/ts/config/webpack.dev.js', null, 'config/webpack.dev.js')(format=".")
  
  :marked
    The development build relies on the Webpack development server which we configure near the bottom of the file.
    
    Although we tell Webpack to put output bundles in the `dist` folder,
    the dev server keeps all bundles in memory; it doesn't write them to disk.
    So we won't find any files in the `dist` folder (at least not any generated from `this development build`).
    
    
    The `HtmlWebpackPlugin` (added in `webpack.common.js`) use the *publicPath* and the *filename* settings to generate 
    appropriate &lt;script&gt; and &lt;link&gt; tags into the `index.html`.
    
    Our CSS are buried inside our Javascript bundles by default. The `ExtractTextPlugin` extracts them into
    external `.css` files that the `HtmlWebpackPlugin` inscribes as &lt;link&gt; tags into the `index.html`.
    
    Refer to the Webpack documentation for details on these and other configuation options in this file
    
    Grab the app code at the end of this guide and try:
    
  code-example(format="").
    npm start
    
  a(id="production-configuration")
  .l-main-section
  :marked
    ### Production Configuration
    
    Configuration of a *production* build resembles *development* configuration ... with a few key changes.
    
  +makeExample('webpack/ts/config/webpack.prod.js', null, 'config/webpack.prod.js')(format=".")
  
  :marked
    We don't use a development server. We're expected to deploy the application and its dependencies to a real production server.
    
    This time the output bundle files are physically placed in the `dist` folder.
    
    Webpack generates file names with cache-busting hash.
    Thanks to the `HtmlWebpackPlugin` we don't have to update the `index.html` file when the hashes changes.
    
    There are additional plugins:
    
    * **NoErrorsPlugin** - stops the build if there is any error.
    * **DedupePlugin** - detects identical (and nearly identical) files and removes them from the output.
    * **UglifyJsPlugin** - minifies the bundles.
    * **ExtractTextPlugin** - extracts embedded css as external files, adding cache-busting hash to the filename.
    * **DefinePlugin** - use to define environment variables that we can reference within our application.
    
    Thanks to the *DefinePlugin* and the `ENV` variable defined at top, we can enable Angular 2 production mode like this:
    
  +makeExample('webpack/ts/src/main.ts', 'enable-prod')(format=".")
    
  :marked
    Grab the app code at the end of this guide and try:
    
  code-example(format="").
    npm run build
    
  a(id="test-configuration")
  .l-main-section
  :marked
    ### Test Configuration
    
    We don't need much configuration to run unit tests. 
    We don't need the loaders and plugins that we declared for our development and production builds.
    We probably don't need to load and process `css` files for unit tests and doing so would slow us down;
    we'll use the `null` loader for all CSS.
    
    We could merge our test configuration into the `webpack.common` configuration and override the parts we don't want or need.
    But it might be simpler to start over with a completely fresh configuration.
    
  +makeExample('webpack/ts/config/webpack.test.js', null, 'config/webpack.test.js')(format=".")
  
  :marked
    Here's our karma configuration:
    
  +makeExample('webpack/ts/config/karma.conf.js', null, 'config/karma.conf.js')(format=".")
  
  :marked
    We're telling Karma to use webpack to run the tests. 
    
    We don't precompile our TypeScript; Webpack transpiles our Typescript files on the fly, in memory, and feeds the emitted JS directly to Karma.
    There are no temporary files on disk.
    
    The `karma-test-shim` tells Karma what files to pre-load and 
    primes the Angular test framework with test versions of the providers that every app expects to be pre-loaded.
    
  +makeExample('webpack/ts/config/karma-test-shim.js', null, 'config/karma-test-shim.js')(format=".")
  
  :marked
  
negative.code: )
  :marked
    ### Highlights:
  
    ### 重点：
  
    * There are no &lt;script&gt; or &lt;link&gt; tags in the `index.html`.
      The `HtmlWebpackPlugin` inserts them dynamically at runtime.
  
    * 在`index.html`中没有&lt;script&gt;或&lt;link&gt;标签。
      `HtmlWebpackPlugin`会在运行时动态插入它们。
  
    * The `AppComponent` in `app.component.ts` imports the application-wide css with a simple `import` statement.
  
    * `app.component.ts`中的`AppComponent`类使用一个简单的`import`语句导入了应用级css。
  
    * The `AppComponent` itself has its own html template and css files which we load with the `require()` method
      supplied by Webpack. Webpack stashes those component-scoped files in the `app.js` bundle too.
  
    * `AppComponent`组件本身有它自己的HTML模板和CSS文件，我们用Webpack提供的`require()`方法加载它们。Webpack还把那些组件内部文件打包进了`app.js`中。
  
    * The `vendor.ts` consists of vendor dependency `import` statements that drive the `vendor.js` bundle.
      The application imports these modules too; they'd be duplicated in the `app.js` bundle
      if the `CommonsChunkPlugin` hadn't detected the overlap and removed them from `app.js`.
  
    * `vendor.ts`由`import`供应商依赖的语句组成，它最终决定了`vender.js`的内容。
      本应用也导入这些模块，如果没有`CommonsChunkPlugin`插件检测出这种重叠，并且把它们从`app.js`中移除，它们就会同时出现在`app.js`包中。
  
  <a id="conclusions"></a>
  :marked
    ## Conclusions
    ## 总结
  
    We've learned just enough Webpack to configurate development, test and production builds
    for a small Angular application.
  
    我们学到了刚好够用来在开发、测试、产品环境下构建一个小型Angular应用的Webpack配置知识。
  
    _We could always do more_. Search the web for expert advice and expand your Webpack knowledge.
  
    _我们还能做得更多_。搜索互联网来获得专家的建议，并扩展你对Webpack的认识。
  
    [Back to top](#top)
  
    [回到顶部](#top)
  