webpack3中文版使用参考文档--全面解析webpack.config.js

Webpack目前官方发布的最新版本是3.1.0,相对于2.0的版本,在语法上没有变更,只是新增了功能。使用webpack,须要事先安装node.js,并对node.js生态有一些基本的了解,好比(npm init 初始化项目,npm install 安装一个包等等)。使用webpack一般有两种方式:1. 命令行方式(CLI) , 2 script方式(推荐)。 两种方式都须要理解webpack概念。javascript

概念

webpack is a module bundler for modern JavaScript applications. When webpack processes your application, it recursively builds a dependency graph that includes every module your application needs, then packages all of those modules into a small number of bundles - often only one - to be loaded by the browser.css

webpack是时下很火的js模块化的打包工具。当用webpack处理你的应用时,它会递归的构建每一个模块的依赖关系图,而后把全部的这些依赖模块打包到一个由数个小块组成的文件中--一般只有一个(将被浏览器加载)html

It is incredibly configurable, but to get started you only need to understand Four Core Concepts: entry, output, loaders, and plugins.前端

虽然它是高度可配置的,可是初步使用你只须要理解下面这四个核心概念:入口,输出,加载器,插件。默认状况下,全部这些配置项,都保存在项目根目录下一个名为webpack.config.js的文件中。vue

一. 入口 (entry) 

The entry point tells webpack where to start and follows the graph of dependencies to know what to bundle. You can think of your application's entry point as the contextual root or the first file to kick off your app.java

所谓的入口,就是告诉webpack从哪里开始并经过依赖关系图得知要哪些文件要打包。你能够理解为应用程序最早读取的文件。读取这个文件以后,就会产生一个模块依赖关系图,那么当前这个文件,就是依赖关系的根。node

webpack.config.jsreact

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

上例告诉webpack从./path/to/my/entry/file.js开始打包,这是最简单的一种入口形式,实际上,它是下面这种形式的简写webpack

module.exports = {
    entry : {
        main : './path/to/my/entry/file.js'
   }  
}

entry 还能够是数组的方式git

module.exports = {
  entry: ['./path/to/my/entry/file.js']
};

这对于不想在js中引入css的状况很是有用,好比:

module.exports = {
  entry: ['./path/to/my/entry/file.js','./path/to/my/entry/file.css']
};

若是是多页应用或者想要提取公共代码(CommonsChunkPlugin)的话,就须要使用下面这种入口方式:

module.exports = {
   entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  }
}     

 固然,这里也可使用数组的形式,同时引入样式或其它文件

module.exports = {
  entry: {
    pageOne: ['./src/pageOne/index.js','./src/pageOne/index.css'],
    pageTwo: ['./src/pageTwo/index.js'],
    pageThree: ['./src/pageThree/index.js']
  }
}

以上就是关于入口这个概念和配置的所有内容了,更详细的介绍请移步官方网站关于入口的扩展介绍 。 除了要告诉webpack要从哪一个文件开始打包以外,还要告诉它打包生成的文件存放在哪一个位置。因而就有了输出的配置。

二. 输出 (output)

webpack的output属性就是告诉webpack怎么对待这些打包的代码。

Configuring the output configuration options tell webpack how to write the compiled files to disk. Note that, while there can be multiple entry points, only one output configuration is specified.

 配置output属性就是告诉webpack把编译后的文件写在磁盘的哪一个地方。注意一点,虽然入口中能够配置成多个文件的形式,可是输出只能指定一个。

--- 打包以后资源,并不老是写在磁盘上,也多是在内存中,好比使用webpack-dev-server的时候。(译者注)

webpack.config.js

const path = require('path');

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

 output有两个属性是必须的。

 1. path 输出路径

  • An absolute path to your preferred output directory.  一般是绝对路径。

 2. filename 文件名

     当入口是多个文件的时候,能够用变量[name]代替固定的名字。这里的name变量,对应entry中的key. ( 对于entry:配置成字符串的时候,输出的文件名就是main,若是不明白,查看前面入口部分的介绍)

module.exports = {
 entry: {
    app: './src/app.js',
    search: './src/search.js'
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  }

}

   在filename属性中,除了[name]以外,还能够用[hash],[contenthash]等内置变量, Tips ! [hash:8] 截取hash前8位

3. publicPath 虚拟路径

  若是你有一个域名或打算用CDN,可使用这个配置,若是你不知道,或暂时不打算用,能够不写。

output: {
  path: "/home/proj/cdn/assets/",
  publicPath: "http://cdn.example.com/assets/",
  filename:'[name].js'
}

 注意:若是配置了publicPath属性,那么本地资源路径,都会被替换成publicPath所指定的地址 (译者注)

 3、加载器

Loaders are transformations that are applied on the source code of a module. They allow you to pre-process files as you import or “load” them. Thus, loaders are kind of like “tasks” in other build tools, and provide a powerful way to handle front-end build steps. Loaders can transform files from a different language (like TypeScript) to JavaScript, or inline images as data URLs. Loaders even allow you to do things like import CSS files directly from your JavaScript modules!

加载器用于将资源代码转换成模块。它容许您在导入或“加载”它们时预处理文件。所以,加载器就像处理各类任务的小工具,它提供一个强大的方法来处理前端构建步骤。加载器能够把不一样类型的文件(好比typescript)转换成javascript 或者把图片处理成内联的数据地址(如base64),加载器甚至能够像导入js模块同样直接导入样式文件。

加载器听起来很历害的样子,不过它不能算是webpack的功能,若是要想在项目中导入样式模块,须要先安装样式的加载器(css-loader), 一样的,要导入图片要安装文件加载器(file-loader)

在命令行中输入:
npm install --save-dev css-loader
便可安装样式加载器,后面跟的参数--save-dev 表示将保存到package.json的开发环境依赖属性中。对应还有一个--save表示安装到生产环境。 package.json文件能够经过手工建立,也可用npm init(推荐)
建立。更多关于package.json的介绍请移步这里

 webpack.config.js

module.exports = {
  module: {
    rules: [
      { test: /\.css$/, use: 'css-loader' }
    ]
  }
};

 加载器位于module属性中(适用于webpack2.0+), rules 是一个数组,里边能够添加多个加载器(loader).  每个加载器用对象的方式组织,下面是一个更为复杂的配置

module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          { loader: 'style-loader' },
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          }
        ]
      }
    ]
  }

 每个加载器,都有各自对应的配置内容,好比css-loader的详细配置请移步这里 ,可是无论怎么说,方法都是同样的。须要指出的事,加载器,除了在webpack.config.js中配置以外,还能够直接在js代码中用行内加载的方式使用,好比

import Styles from 'style-loader!css-loader?modules!./styles.css'; //多个加载器之间用!进行分隔

不过这种方式写起来很冗长,不推荐。还有一种方式,也一并提一下,在CLI方式中的使用



webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

一样的冗长,了解一下便可,实际项目中,大可能是使用webpack.config.js进行集中配置。

通常来讲,一个加载器就能够完成一个任务,好比file-loader 能够加载文件到js的模块中,但是咱们经常发现,加载css到js模块中,除了使用css-loader以外,经常还有一个或多个附加的伴侣,好比这个style-loader。

这是为何呢? 这实际上是由于样式的使用有两种方式,一种是内联的方式,写在html的style标签中,还有一种是外链,经过link的方式引用。而咱们在开发环境中,css是做为js的模块打包进js文件中的。并且js要使用样式,必须在html中插入style标签,而后把样式以字符串的形式插入标签内。因此这里须要用到两个加载器,首先用css-loader把样式读取到js的模块中,然用style-loader写入style标签中。因此也就出现了css-loader和style-loader成对使用的状况。对于同时使用多个加载器的状况,它们的调用顺序是从右向左的。也就是说最早使用的要写在最右边,对于新式这个例子来讲,就是style-loader!css-loader这样写。关于style-loader这个加载器,其实它还有一个少被人提起,却很是有用的功能--热替换,这部份内容后面再细说

有人不由要问,既然css能够直接用link的方式使用,为何不把css打包成独立的css文件呢?这样我就不须要用style-loader了,并且把样式内联在html中,看着不舒服。好吧,这就不得不引出webpack中的第四个概念了---插件

4、 插件 plugins

They also serve the purpose of doing anything else that a loader cannot do.

插件用于完成一些载器所不能作的事情。

其实这样解释不并是很严谨,可是插件,确实使的webpack更增强大了。回到前说的独立样式的问题,结合插件来作。

先安装extract-text-webpack-plugin 这个插件

npm install --save-dev extract-text-webpack-plugin

var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var node_modules_dir = path.resolve(__dirname, '../node_modules');

module.exports = {
    entry: {
        home:'./src/home.es6'
    },
    module: {
        rules:[{
                test:/\.css/,
                use: ExtractTextPlugin.extract({
                  fallback: "style-loader",
                  use: ["css-loader","postcss-loader"]
                })
            }
        ]
    },
    output: {
        path: path.resolve(__dirname,"../dist"),
        filename: 'js/[name][hash:7].js'
    },
    plugins: [
        new ExtractTextPlugin({
            filename: "css/[name].[contenthash].css"
        }),
        new webpack.optimize.UglifyJsPlugin()
    ],
}

 new webpack.optimize.UglifyJsPlugin() //用来压缩代码,这个是webpack送的,不须要单独安装, new ExtractTextPlugin 用来提取css到一个独立的样式文件,这个插件须要本身安装,还要在loader中进行相应的改动,配合使用才能生效。值得注意的是,这样一来,就牲牺了css的热替换能力了。不过无所谓,这个插件通常用在生产环境打包。

Hot Module Replacement  (HMR热替换) 

这应当属于webpack中比较高级的内容了,可是在开发中,结合热替换一块儿使用,会很方便。最简单的使用方式是经过 webpack-dev-server --hot

关于这一部分的内容,参考我之前写的一篇文章。官方介绍移步这里这里须要指出的是,并非加了--hot就能够实现热替换,这须要对应的加载器支持“热替换”才行的。

好比前面说的样式,style-loader是能够支持热替换的。并且对于js来讲,虽然webpack不须要额外的加载器就能够进模块化,可是并不支持“热替换", 若是使用react.js的话,能够用react-hot-loader,若是用Vue的话,能够用vue-loader。 若是该加载器不支持热替,会降级为自动刷新。所以,热替换,并非自动刷新哦。

总结

 webpack3还比较新,若是以前使用webpack2的项目,直接升级到webpack3的话,须要当心了,有些加载器和插件可能不支持webpack3. 好比提取css为独立文件的插件,就不支持。webpack-dev-server也不支持 (至少在我写这篇文章的时候仍是不支持的),可是不能因噎废食,新技术最终会取替旧技术,这是行业趋势。安于现状,只会被淘汰。webpack的学习最好是本身写一个简单项目,把文章提到的和本身学到的loader,plugin都试试。把基本的概念和用法型明白以后,能够安装别人写的比较优盘的项目拿来对照学习,好比Vue-cli。看看行业大牛们,是怎么配置webpack的,他们都用了哪些插件和加载器。最后,我也提供一下本身练习的项目,作为本篇的结尾。https://github.com/bjtqti/font-end-boilerplate.git 

相关文章
相关标签/搜索