[译] Webpack 入门指南

阅读 5391
收藏 296
2016-05-16
原文链接:sugarball.me

原文

Webpack是目前最火的前端自动化工具,它是一个module bundler并和大部分现代前端相关模块完美结合,包括Babel,ReactJS等等。本文从新手的角度一步一步用webpack配置一个react项目。

安装

首先要知道:

  1. Webpack和NPM配合比较好,Bower泪目。
  2. Webpack会使用模块系统,CommonJS ES6等。

全局安装Webpack:

npm install webpack -g  
最简单的build

创建两个文件 index.html & app.js

app.js

document.write('welcome to my app');  
console.log('app loaded');  

index.html

  
  
    
  
  

在控制台里运行:

webpack ./app.js bundle.js  

这个命令使用我们刚创建的app.js文件的相对路径作为第一个参数,表示这是我们希望的js文件入口,后面的参数则是我们希望build完成后webpack为我们创建的文件。这样就完成了最简单的webpack的build。

定义一个配置文件

Webpack中的配置文件基本上是一个commonJS模块。配置文件里面放了我们需要的配置项,loader(后面讲)还有一些其他的属性。

在刚才的那个目录定义一个webpack.config.js,这就是我们的Webpack配置文件,加入以下代码:

module.exports = {  
  entry: "./app.js",
  output: {
    filename: "bundle.js"
  }
}

entry---该属性指的是我们文件的最顶层的入口,它可以是一个文件也可以是一个文件数组。在这里,我们就传入app.js。

output---该属性指的是输出文件。我们这里只给它指定一个名字bundle.js。

现在我们简单的运行:

webpack  

这样Webpack就会按照配置文件的属性,完成build。

其他配置项

Watchmode

当配置了Watchmode,每当又文件修改的时候,Webpack都会自动重新build。

启用Watchmode有两种方式:

1.命令行

webpack --watch  

2.在config.js中加入watch属性配置,并设为true

module.exports = {  
  entry: "./app.js",
  output: {
    filename: "bundle.js"
  }, 
  watch: true
}

Webpack Dev Server

Webpack自己有一个web server叫Webpack Dev Server。
可以在控制台全局安装:

npm install webpack-dev-server -g  

然后启动:

webpack-dev-server  

alt

然后你可以访问http://localhost:8080/webpack-dev-server/就可以看到你的应用。

Webpack官方文档:

Dev server使用了watch模式。并且阻止了webpack将build结果输出到硬盘上,而是从内存中读取。这意味这你看不到打包好的bundle.js。如果你需要,则还是要运行webpack命令。

在dev server运行时,你本地的任何修改都会让浏览器自动刷新(hot-loading)。

默认hot-loading是打开的。如果你想禁用或者移除页面顶部的页面状态,则可以直接访问http://localhost:8080/

如果你只是单纯的想移除状态条,不想禁用hot-loading,则可以运行:

webpack-dev-server --inline  

然后访问http://localhost:8080/

打包多个文件

1.require文件

为了展示webpack怎么打包多个文件,我们加入logger.js,代码就是打个log:

console.log('logger.js is now loaded...');  

在app.js中require该文件:

require('./logger');  

然后重新运行webpack-dev-server,你可以看到log正常输出。

2.在webpack.config.js中添加多个文件入口

我们添加一个和app.js没有关系的js文件,global.js:

console.log('global.js is now loaded...');  

然后修改webpack.config.js:

module.exports = {  
  entry: ["./global.js", "./app.js"],
  output: {
    filename: "bundle.js"
  }
}

同样,重新运行dev server,可以看到global.js的log也输出了。

Webpack loaders 和 preloaders

可以这么理解,loader是webpack学习新功能的渠道。(这里译者多说两句,webpack相对gulp等简化了很多的配置,不需要开发人员去配置压缩插件,合并插件等等,给人的感觉就是gulp是零散的工具,而webpack是一套标准的解决方案,但是怎么给这套方案添砖加瓦呢,这就是loader的功能了。)

官方文档:Loader允许使用require或者‘load’对它们进行预处理。Loader和其他构建工具里面的task任务很像,提供了前端一套完整的步骤。Loader可以转义,比如将CoffeeScript转成JavaScript。甚至可以在JS文件中require样式css文件。

下面我们举例安装两个常用的loader:Babel和JSHint。首先我们需要安装这些npm模块。

npm install babel-core babel-loader jshint jshint-loader node-libs-browser babel-preset-es2015 babel-preset-react webpack  --save-dev  

babel-core即babel的包。

babel-loader即babel的webpack loader。

jshint即js语法检测器。

jshint-loader即JSHint的webpack loader。

node-libs-browser提供了wepack浏览器使用的node模块。

babel-preset-es2015及es2015的babel预设。

babel-preset-react是babel针对react的预设。

Webpack配合Babel使用

ok,让我们写点es6,看看webpack能不能配合babel打包。

1.打开logger.js,改成下面这样:

let checkName= (firstName, lastName) => {  
 if(firstName !== 'nader' || lastName !== 'dabit') {
   console.log('You are not Nader Dabit');
 } else {
    console.log('You are Nader Dabit');
  }
}
checkName('nader', 'jackson');  

2.将logger.js重命名为logger.es6

3.打开webpack.config.js,添加babel loader:

module.exports = {  
 entry: ["./global.js" , "./app.js"],
 output: {
   filename: "bundle.js"
 },
 module: {
   loaders: [
     {
       test: /\.es6$/,
       exclude: /node_modules/,
       loader: 'babel-loader',
       query: {
         presets: ['react', 'es2015'] 
       }
     }
   ]
 },
 resolve: {
   extensions: ['', '.js', '.es6']
 },
}

我们逐一解释一下这些关键字:

  1. test: 检测哪些文件需要此loader,是一个正则表达式,这里我们过滤所有es6后缀的文件。
  2. exclude: 忽略哪些文件,这里我们忽略node_module中的文件。
  3. loader: 我们将使用的loader。
  4. query: 我们传给loader的属性。
  5. cacheDirectory: 默认为false,设置之后,会将build文件换成在配置的文件夹中,然后之后的build就会从cache中读取,避免多次build的缓慢。
  6. presets:我们这里使用刚安装的react和es2015.

我们这里还配置了一个‘ resolve‘属性,reslove帮助我们配置那些后缀的文件是需要处理的,我们不需要在代码中写定后缀名,比方说,我们可以写:

require('./logger');  

而不需要写:

require('./logger.es6');  

搞定,现在重新运行dev server可以看到结果“You are not Nader Dabit”。

Preloaders: 使用JSHint

Preloader是在loader运行之前运行的,这里我们用JSHint作为示例:

module.exports = {  
 entry: ["./global.js" , "./app.js"],
 output: {
   filename: "bundle.js"
 },
 module: {
   preLoaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'jshint-loader'

      }
   ],
   loaders: [
     {
       test: /\.es6$/,
       exclude: /node_modules/,
       loader: 'babel-loader',
       query: {
          cacheDirectory: true, 
          presets: ['react', 'es2015'] 
       }
      }
   ]
 },
 resolve: {
   extensions: ['', '.js', '.es6']
 }
}

重启,可以看到JSHint运行并报了一个错误: alt

创建Start脚本

我们经常配合npm的package.json使用webpack,可以把脚本写在npm script中简化要手动敲的命令。

在package.json中添加:

"scripts": {
  "start": "webpack-dev-server"
},

然后运行:

npm start  

这样写也方便我们以后需要添加更多的选项。

开发环境和产线环境分离

产线bundle

一个production的bundle会压缩代码,在webpack中很简单:

webpack -p  

加个-p属性就可以了。

使用多个webpack config文件

首先创建一个webpack-production.config.js作为我们产线打包的配置文件,我们这里安装strip-loader,它会帮我们过滤代码中不需要出现在产线的那部分,比方console.log:

npm install strip-loader --save-dev  

然后在webpack-production.config.js加入:

var WebpackStripLoader = require('strip-loader');  
var devConfig = require('./webpack.config.js');  
var stripLoader = {  
 test: [/\.js$/, /\.es6$/],
 exclude: /node_modules/,
 loader: WebpackStripLoader.loader('console.log')
}
devConfig.module.loaders.push(stripLoader);  
module.exports = devConfig;  
  1. WebpackStripLoader引入strip-loader
  2. devConfig包含我们之前在webpack.config.js中的配置。
  3. devConfig.module.loaders.push(stripLoader)将此loader塞入webpack.config.js定义的loader数组中。

然后在控制台运行:

webpack --config webpack-production.config.js -p  

这样我们就为产线build了一个压缩的并没有console.log的js文件。

React 和 Webpack

好,我们现在把react加进去。首先安装react:

npm install react react-dom --save  

然后创建一个react组件hello.js:

import React from "react";  
export default React.createClass({  
 render: function() {
   return (
     
Hello, {this.props.name}!
); }, });

打开我们之前的app.js,改成:

import React from "react";  
import ReactDOM from "react-dom";  
import Hello from "./hello";  
ReactDOM.render(  
  ,
  document.body
);

最后修改webpack.config.js,给babel-loader的test属性添加js后缀文件过滤。这样babel就会去解析js文件,我们就可以在js中使用jsx了。重启dev server,搞定!

评论