Thanks to Webpack 傻瓜式指南

安装

npm install -g webpack
`</pre>

### 建立项目

<pre>`mkdir webpack
cd webpack
npm init
touch .gitignore
`</pre>

#### 项目结构

<pre>`project
|
|---app
|    |
|    |---index.js
|    |---sub.js
|
|---package.json
|
|---webpack.config.js
`</pre>

<pre>`//sub.js
function generateText(){
  var element = document.createElement('h2');
  element.innerHTML = "Hello, I'm h2";
  return element;
}
module.exports = generateText;
`</pre>

<pre>`//index.js
var sub = require('./sub');
var app = document.createElement('div');
app.innerHTML = "&lt;h1&gt;Hello, I'm h1";
app.appendChild(sub())
`</pre>

### 配置 Webpack

目的是将两个 js 根据依赖关系合并, 然后在 dist 目录创建一个 index.html 并引用合并后的 js.

这里安装一个 plugin, 可以快速生成 HTML

<pre>`npm install --save-dev html-webpack-plugin
`</pre>

修改 webpack.config.js

<pre>`var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
//定义文件夹路径
var ROOT_PATH = path.resolve(__dirname);
var APP_PATH = path.resolve(ROOT_PATH, 'app');
var DIST_PATH = path.resolve(ROOT_PATH, 'dist');

module.exports = {
  //项目文件夹, 可以直接用文件夹名, 默认寻找 index.js
  entry: APP_PATH,
  output: {
    path: DIST_PATH,
    filename: 'bundle.js'
  },
  //添加插件, 自动生成 html
  plugins: [
    new HtmlWebpackPlugin({title: 'Hello World App'})
  ]
};
`</pre>

然后在项目目录运行

<pre>`webpack
`</pre>

可以看到 html 已经引用了 bundle.js

### 配置 webpack-dev-server

用于自动刷新浏览器

安装webpack-dev-server

<pre>`npm install -g webpack-dev-server
`</pre>

修改 webpack.config.js

<pre>`module.exports = {
  ...
  devServer: {
    historyApiFallback: true,
    hot: true,
        inline: true,
    progress: true,
  },
  ...
}

`</pre>

修改 package.json

<pre>`...
"scripts": {
  "start": "webpack-dev-server --hot --inline"
},
...
`</pre>

在项目目录执行

<pre>`npm start
`</pre>

登录 http://localhost:8080

### 添加 CSS 样式

css-loader 会遍历 css 文件, style-loader 会把样式插入到&lt;style&gt;

<pre>`npm install -save-dev css-loader style-laoder
`</pre>

修改 webpack.config.js

<pre>`...
module:{
  loaders: [
    {
      test: /\.css$/,
      loaders: ['style','css'],
      include: APP_PATH
    }
  ]
}
...
`</pre>

注意 loaders 的书写方式, 从右向左执行

添加样式文件 app/main.css

<pre>`h1 {
  color: red;
}
`</pre>

在入口文件"index.js" 中引用

<pre>`require('./main.css')
`</pre>

### 使用 sass

这里需要 sass-loader 和 node-sass 一起解析文件

<pre>`npm install --save-dev sass-loader node-sass
`</pre>

修改 webpack.config.js

<pre>`//先删除 css 规则
{
  test: /\.scss$/,
  loaders: ['style','css','sass'],
  include: APP_PATH
},
`</pre>

添加两个 sass 文件 app/variables.scss 和 app/main.scss

<pre>`//variables.scss
$red: red;
`</pre>

<pre>`//main.scss
@import './variables.scss';
h1{
  color: $red;
}
`</pre>

在入口文件 index.js 中引用

<pre>`require('./main.scss');
`</pre>

### 处理图片

<pre>`npm install --save-dev url-loader
`</pre>

配置webpack.config.js

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

注意, Limit参数制定了小于 8M 的图片会被转为 base64 编码, 可以减轻网络请求.

<pre>`@import './variabels.scss'
h1 {
  color: $red;
  background-image: url('./imgs/avatar.jpg');
}
`</pre>

### 添加第三方库

<pre>`npm install --save-dev jquery moment
`</pre>

修改 index.js

<pre>`var sub = require('./sub');
require('./main.scss');
var $ = require('jquery');
var moment = require('moment');
var app = document.createElement('div');
app.innerHTML = '&lt;h1&gt;Hello, h1';
document.body.append(app);
app.appendChild(sub());
$('body').append('&lt;p&gt;Inserted By Jquery. Now is ' + moment().format() + '&lt;/p&gt;');
`</pre>

### 添加 ES6 支持

安装 loader

<pre>`npm install -save-dev babel-loader babel-preset-es2015
`</pre>

配置 webpack.config.js

<pre>`...
{
  test: /\.jsx$/,
  loaders: babel,
  include: APP_PATH,
  query:{
    presets: ['es2015']
  }
}
...
`</pre>

es2015 这个参数是 babel 的 plugin, 可以支持最新的 ES6 的特性

现在可以 js 文件改为 ES6 风格

<pre>`//sub.js
export default function(){
  var element = document.createElement('h2');
  element.innerHTML = 'This is h2';
  return element;
}
`</pre>

<pre>`//index.js
import './main.scss';
import generateText from './sub';
import $ from 'jquery';
import moment from 'moment';

let app = document.createElement('div');
const myPromise = Promise.resolve(42);
myPromise.then((number) =&gt; {
  $('body').append('&lt;p&gt;Promise result is ' + number + 'now is ' + moment().format() + '&lt;/p&gt;');
});
app.innerHTML = '&lt;h1&gt;This is h1';
document.body.appendChild(app);
app.appendChild(generateText());