阳光博文 你的空间 知识的容器

webpack的安装及使用教程

介绍

WebPack 是一个模块打包工具,你可以使用WebPack管理你的模块依赖,并编绎输出模块们所需的静态文件。它能够很好地管理、打包Web开发中所用到的HTML、Javascript、CSS以及各种静态文件(图片、字体等),让开发过程更加高效。

为了将模块化技术用于浏览器,人们造出了一大堆工具比如:RequireJSBrowserifyLABjsSea.jsDuo等。同时,由于Javascript的标准没有对模块的规范进行定义,所以伟大的程序员们又定义了一系列不同的模块定义,比如:CommonJSAMDCMDUMD等。

Webpack同时支持同步模式(CommonJS)和异步模式(AMD形式)的模块

webpack的优势:

  • require.js的所有功能它都有

  • 编绎过程更快,因为require.js会去处理不需要的文件

安装方法

我们在全局环境的安装方法如下:

$ sudo npm install webpack -g

实例

首先在根目录创建一个名为test的项目文件夹,里面放一个main.js的文件,代码如下:

document.write("It works.");

再创建一个index.html文件,代码如下:

<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <script type="text/javascript" src="bundle.js" charset="utf-8"></script>
    </body>
</html>

这里的bundle.js是用webpack打包编译后生成的文件。执行编译如下:

$ webpack ./test/main.js bundle.js

然后就会在终端生成如下代码:

Hash: 4447402abfcd89f9daba
Version: webpack 1.9.7
Time: 78ms
    Asset     Size  Chunks             Chunk Names
bundle.js  1.44 kB       0  [emitted]  main
   [0] ./test/main.js 28 bytes {0} [built]

这时双击打开index.html文件就会看到It works. 字样

剩下例子看这里:http://webpack.github.io/docs/tutorials/getting-started/

CommonJS

服务器端的 Node.js 遵循 CommonJS规范,该规范的核心思想是允许模块通过 require 方法来同步

加载所要依赖的其他模块,然后通过 exportsmodule.exports 来导出需要暴露的接口。


require("module");

require("../file.js");

exports.doStuff = function() {};

module.exports = someValue;

AMD

Asynchronous Module Definition 规范其实只有一个主要接口 define(id?, dependencies?, factory),它要在声明模块的时候指定所有的依赖 dependencies,并且还要当做形参传到 factory 中,对于依赖的模块提前执行,依赖前置。


define("module", ["dep1", "dep2"], function(d1, d2) {
  return someExportedValue;
});
require(["module", "../file"], function(module, file) { /* ... */ });

优点:

  • 适合在浏览器环境中异步加载模块

  • 可以并行加载多个模块

CMD

Common Module Definition 规范和 AMD 很相似,尽量保持简单,并与 CommonJSNode.js

Modules 规范保持了很大的兼容性。


define(function(require, exports, module) {

  var $ = require('jquery');

  var Spinning = require('./spinning');

  exports.doSomething = ...

  module.exports = ...

})

优点:

  • 依赖就近,延迟执行

  • 可以很容易在 Node.js 中运行

对于全局安装的webpack,直接执行此命令会默认使用当前目录的webpack.config.js作为配置文件。

通常我们会将 Webpack 安装到项目的依赖中,这样就可以使用项目本地版本的 Webpack


# 进入项目目录
# 确定已经有 package.json,没有就通过 npm init 创建
# 安装 webpack 依赖
$ npm install webpack --save-dev//生成如下的代码
 "devDependencies": {
    "webpack": "^1.12.9"
  }

entry参数

定义了打包后的入口文件,可以是数组(所有文件打包生成一个filename文件),对象或者字符串



{

    entry: {

        page1: "./page1",

        page2: ["./entry1", "./entry2"]

    },

    output: {

        // Make sure to use [name] or [id] in output.filename

        //  when using multiple entry points

        filename: "[name].bundle.js",

        path: "dist/js/page",

        chunkFilename: "[id].bundle.js"

    }

}


该段代码最终会生成一个 page1.bundle.jspage2.bundle.js,并存放到 ./dist/js/page 文件夹下

output参数是个对象,定义了输出文件的位置及名字:

path: 打包文件存放的绝对路径
publicPath: 网站运行时的访问路径
filename:打包后的文件名

Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。

不同模块的加载是通过模块加载器(webpack-loader)来统一管理的。Loader 可以理解为是模块和资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。



module: {

        //加载器配置

        loaders: [

            //.css 文件使用 style-loader 和 css-loader 来处理

            { test: /\.css$/, loader: 'style-loader!css-loader' },

            //.js 文件使用 jsx-loader 来编译处理

            { test: /\.js$/, loader: 'jsx-loader?harmony' },

            //.scss 文件使用 style-loader、css-loader 和 sass-loader 来编译处理

            { test: /\.scss$/, loader: 'style!css!sass?sourceMap'},

            //图片文件使用 url-loader 来处理,小于8kb的直接转为base64

            { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}

        ]

    }

Loader 可以通过 npm 发布和安装。
用来定义loader的串联关系,”-loader”是可以省略不写的,多个loader之间用“!”连接起来,但所有的加载器都需要通过npm来加载。loaders接受查询参数,可以用于传递配置项给loader

我们要在页面中引入一个 CSS 文件 style.css,首页将 style.css 也看成是一个模块,然后用 css-loader 来读取它,再用 style-loader 把它插入到页面中。

我们可以根据模块类型(扩展名)来自动绑定需要的 loader。

将 entry.js 中的 require("!style!css!./style.css") 修改为 require("./style.css") ,然后执行:


$ webpack entry.js bundle.js --module-bind 'css=style!css'

安装 loader:


npm install css-loader style-loader

resolve

webpack在构建包的时候会按目录的进行文件的查找,resolve属性中的extensions数组中用于配置程序可以自行补全哪些文件后缀。extensions 第一个是空字符串,对应不需要后缀的情况.

externals

当我们想在项目中require一些其他的类库或者API,而又不想让这些类库的源码被构建到运行时文件中,

这在实际开发中很有必要。此时我们就可以通过配置externals参数来解决这个问题:


 externals: {

     "jquery": "jQuery"

 }

这样我们就可以放心的在项目中使用这些API了:var jQuery = require(“jquery”);

常用命令


webpack 最基本的启动webpack命令

webpack -w 提供watch方法,实时进行打包更新

webpack -p 对打包后的文件进行压缩

webpack -d 提供SourceMaps,方便调试

webpack --colors 输出结果带彩色,比如:会用红色显示耗时较长的步骤

webpack --profile 输出性能数据,可以看到每一步的耗时

webpack --display-modules 默认情况下 node_modules 下的模块会被隐藏,加上这个参数可以显示这些被隐藏的模块

Webpack开发服务器需要单独安装,同样是通过npm进行:


npm install -g webpack-dev-server

可以使用webpack-dev-server直接启动,也可以增加参数来获取更多的功能,

具体配置可以参见官方文档。默认启动端口8080,通过 localhost:8080

可以访问页面,文件修改后保存时会在页面头部看到sever的状态变化,并且会进行热替换,实现页面的自动刷新。

当项目逐渐变大,webpack 的编译时间会变长,可以通过参数让编译的输出内容带有进度和颜色。


$ webpack --progress --colors

Webpack 的配置提供了 resolveresolveLoader 参数来设置模块解析的处理细节,resolve 用来配置应用层的模块(要被打包的模块)解析,resolveLoader 用来配置 loader 模块的解析。


 var webpack = require('webpack');

module.exports = {

    entry: './entry.js',//入口文件

    output:{

        path: __dirname,//输出目录

        filename: 'bundle.js'//输出文件名

    },

    //module 的作用是添加loaders

    module:{

        loaders: [

            {

                test:/\.css$/,//test属性匹配css文件

                loader: 'style!css'//加载style和css loader

            }

        ]

    },

    //Webpack 本身内置了一些常用的插件,还可以通过 npm 安装第三方插件。

    plugins:[

        new webpack.BannerPlugin('this file is created by trigkit4')//BannerPlugin 内置插件来实践插件的配置和运行,这个插件的作用是给输出的文件头部添加注释信息。

    ],

    resolve: { fallback: path.join(__dirname, "node_modules") },

    resolveLoader: { fallback: path.join(__dirname, "node_modules") }

};

Webpack 中涉及路径配置最好使用绝对路径。

list of Loader

http://webpack.github.io/docs/list-of-loaders.html

Babel-loader can transform JSX/ES6 file into JS file


npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save-dev

你可以在webpack里require进来css文件,然后通过CSS-loader预处理css文件

webpack-dev-server

webpack-dev-server是一个小型的node.js Express服务器,它使用webpack-dev-middleware中间件来为通过webpack打包生成的资源文件提供Web服务。它还有一个通过Socket.IO连接着webpack-dev-server服务器的小型运行时程序。webpack-dev-server发送关于编译状态的消息到客户端,客户端根据消息作出响应。

webpack-dev-server有两种模式支持自动刷新——iframe模式和inline模式。在iframe模式下:页面是嵌套在一个iframe下的,在代码发生改动的时候,这个iframe会重新加载;在inline模式下:一个小型的webpack-dev-server客户端会作为入口文件打包,这个客户端会在后端代码改变的时候刷新页面。

http://localhost:8080/webpack-dev-server/index.html

使用inline模式:命令行方式
1) 命令行方式比较简单,只需加入--line选项即可。例如:
webpack-dev-server --inline

插件

webpack+reactjs的使用

webpack.config.js文件:

var webpack = require('webpack');
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
module.exports = {
    entry: './entry.jsx',
    output: {
        filename: 'bundle.js'
    },
    module:{
        loaders:[
            {
            test:/\.js[x]?$/,
            loader: 'babel-loader',
            exclude:/node_modules/,
            query:{
                presets: ['es2015','react']
            }
        },
            {
                test: /\.css$/,
                loader: 'style-loader!css-loader?modules'
            }
        ]
    },
    plugins: [
        new uglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
    ]

};

package.json文件


{
  "name": "reactdemo",
  "version": "1.0.0",
  "description": "reactdemos",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "trigkit4",
  "license": "ISC",
  "dependencies": {
    "babel-preset-react": "^6.3.13",
    "react": "^0.14.5",
    "react-dom": "^0.14.5"
  },
  "devDependencies": {
    "babel-core": "^6.3.26",
    "babel-loader": "^6.2.0",
    "babel-preset-es2015": "^6.3.13",
    "babel-preset-react": "^6.3.13",
    "webpack": "^1.12.9"
  }
}

index.html文件:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="example"></div>
<script src="bundle.js"></script>
</body>
</html>

entry.jsx文件

const React = require('react');
const ReactDOM = require('react-dom');
var style = require('./app.css');
var Input = React.createClass({
    getInitialState: function () {
        return{
            value: 'hello'
        }
    },
    handleChange: function(event){
        this.setState({
            value: event.target.value
        })
    },
    render: function(){
        var value = this.state.value;
        return(
            <div>
                <input type="text" value={value} onChange={this.handleChange}/>
                <p>{a}</p>
            </div>
        )
    }
});
var a = React.createElement('a',{
    className: 'link',
    href: 'https://www.baidu.com'
},'React');//<a class='link' href='https://www.baidu.com'>React</a>
ReactDOM.render(
    <Input/>,
    document.getElementById('example')
);

app.css文件

html{
    font-size: 10px;
}
p{
    font-size: 1.6rem;
}
input[type=text]{
    color: red;
    font-size: 1.2rem;
}

http://webpack.github.io/docs/list-of-plugins.html

github地址:https://github.com/webpack/webpack


在线咨询