webpack2快速入门的几个实例

本文是在请练完这16个webpack小例子基础上补充的webpack2的版本

安装

$ npm i -g webpack webpack-dev-server

配置

配置文件为 webpack.config.js

module.exports = {
  entry: './main.js', // 入口文件
  output: {
    filename: 'bundle.js' //打包后的文件名
  }
};

命令行

  1. webpack 构建文件
  2. webpack -p 发布
  3. webpack --watch 监听项目
  4. webpack -d 包含source map方便调试
  5. webpack --colors让打包界面更好看

在package.json中配置命令

{
  // ...
  "scripts": {
    "dev": "webpack-dev-server --devtool eval --progress --colors",
    "deploy": "NODE_ENV=production webpack -p"
  },
  // ...
}

使用

单文件入口

module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'
  }
};

多文件入口

module.exports = {
  entry: {
    bundle1: './main1.js',
    bundle2: './main2.js'
  },
  output: {
    filename: '[name].js'
  }
};

引用

<html>
  <body>
    <script src="bundle1.js"></script>
    <script src="bundle2.js"></script>
  </body>
</html>

loaders

某些规律

在loaders的每个对象中,

  1. 使用多个loader,用!连接
  2. 传递参数是在loader名字后面加?,多个参数用&连接

babel-loader

module.exports = {
  entry: './main.jsx',
  output: {
    filename: 'bundle.js'
  },
  module: {
    loaders:[
      {
        test: /\.js[x]?$/,
        exclude: /node_modules/,
        loader: 'babel-loader?presets[]=es2015&presets[]=react'
      },
    ]
  }
};

module.loaders 区域是用来分配loader的. 像上面的代码片段使用了 babel-loader 需要安装插件 babel-preset-es2015 和 babel-preset-react to 编译成 ES6 and React. 可以用query配置参数

module: {
  loaders: [
    {
      test: /\.jsx?$/,
      exclude: /node_modules/,
      loader: 'babel',
      query: {
        presets: ['es2015', 'react']
      }
    }
  ]
}

css-loader style-loader

先在css-loader中读取css文件,这里为main.js
注意移动在某个js文件中引入css文件

// main.js
require ('./xxx.css')

之后再style-loader中将样式插入到html中

module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'
  },
  module: {
    loaders:[
      { test: /\.css$/, loader: 'style-loader!css-loader' },
    ]
  }
};

image-loader

参数前是用?连接的

依然和处理css格式的文件一样,需要在main.js中require,然后用fileloader

var img1 = document.createElement("img");
img1.src = require("./small.png");
document.body.appendChild(img1);

转换为图片文件

module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'
  },
  module: {
    loaders:[
      { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
    ]//url-loader 转换图片文件. 如果图片的大小小于 8192 bytes,它将会转成base64位的地址; 相反, 它就是普通地址. 
  }
};

Module

css module

CSS Module可以开启全局变量和局部变量,:global(...)表示全局变量,可以在全局中使用样式
更多配置

:global(.h2) {
  color: blue;
}

main.jsx

var React = require('react');
var ReactDOM = require('react-dom');
var style = require('./app.css');

ReactDOM.render(
  <div>
    <h1 className={style.h1}>Hello World</h1>
    <h2 className="h2">Hello Webpack</h2>
  </div>,
  document.getElementById('example')
);
module.exports = {
  entry: './main.jsx',
  output: {
    filename: 'bundle.js'
  },
  module: {
    loaders:[
      {
        test: /\.js[x]?$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015', 'react']
        }
      },
      {
        test: /\.css$/,
        loader: 'style-loader!css-loader?modules'
      }
    ]
  }
};

使用composes

如需要引用以下两个css文件:

style1.css

.text1{
    ......
    color:yellow;
}

style2.css

.text2{...}

定义一个main.css供于继承并引用

.context1{
    composes:text1 from "path/style1.css";
    color:red; // 这里会覆盖原有样式
}
.context2{
    composes:text2 from "path/style2.css";
    color:blue;
}

在main.js中

import styles from './main.css';
import React, { Component } from 'react';
export default class varA extends Component {
  render() {
    return (
      <div className={styles.context1}>
        <p className={styles.context2}>Style Variant A</p>
      </div>
    );
  }

};

css动画的处理

anime.css

@keyframes bounce {
  33% { transform: translateY(-20px); }
  66% { transform: translateY(0px); }
}
.bounce {
  animation: bounce 1s infinite ease-in-out;
}

main.css

.bounce{
    composes: bounce from 'path/anime.css'
    background-color:red;
}

main.js

import styles from './main.css';
import React, { Component } from 'react';
export default class  varB extends Component {
  render() {
    return (
      <div className={styles.bounce}>
      </div>
    );
  }
}

Plugins

UglifyJs Plugin

可以优化代码,去掉本身附加的东西,减小js代码量

var webpack = require('webpack');
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'
  },
  plugins: [
    new uglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
};

经过打包后,main.js将会压缩为

var o="Hello";o+=" World",document.write("<h1>"+o+"</h1>")

相关配置

链接

html webpack plugin & open browser webpack plugin

html-webpack-plugin 创建 index.html,open-browser-webpack-plugin 打开浏览器
HtmlwebpackPlugin只支持node7

var HtmlwebpackPlugin = require('html-webpack-plugin');
var OpenBrowserPlugin = require('open-browser-webpack-plugin');

module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlwebpackPlugin({
      title: 'Webpack-demos',
      filename: 'index.html'
    }),
    new OpenBrowserPlugin({
      url: 'http://localhost:8080'
    })
  ]
};

环境变量

设置环境变量控制特定的代码输出路径

var webpack = require('webpack');
module.exports = function() {
      return {
          entry: './main.js',
          output: {
              filename: 'bundle.js'
          },
        plugins: [
            new webpack.EnvironmentPlugin(['NODE_ENV', 'DEBUG'])
    ]
      };
};
// main.js
document.write('<h1>Hello World</h1>');
if (process.env.NODE_ENV === 'production') {
    console.log('Welcome to production');
}
if (process.env.NODE_ENV === 'development') {
    console.log('Welcome to development'); // show
}
if (process.env.DEBUG) {
    console.log('Debugging output'); // show
}

注意:先命令行执行 set NODE_ENV=development,之后再wds

code splitting

a.js

module.export="i will be compiled to 0.bundle.js"

main.js

function determinated(){
  // import()中不能写入变量!!
  import('./a').then((a)=>{
      document.open()
        document.write(`<h1>${a}</h1>`)
        document.close()
    }).catch((err)=>{
    console.log(err)
    })
}
determinated()

webpack.config.js不变,但最后编译出来的代码被分成了两个部分。

CommonsChunkPlugin

CommonsChunkPlugin是一个选择性功能,可以创建一个单独的文件(称为一个块),由多个入口点之间共享的通用模块组成。通过将公共模块与捆绑分开,生成的分块文件最初可以加载一次,并存储在高速缓存中供以后使用。这会使页面优化,因为浏览器可以快速提供来自缓存的共享代码,而不是每当访问新页面时被强制加载更大的包

// webpack.config.js
//CommonsChunkPlugins是webpack自身的方法,功能是提取两个方法共有的代码模块
var webpack = require('webpack');
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");

module.exports = {
    entry: {
        bundle1: './main1.jsx',
        bundle2: './main2.jsx'
    },
    output: {
        filename: '[name].js'
    },
    module: {
        loaders: [
            {test: /\.js[x]?$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react'},
        ]
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: "init'",
            filename: "init.js",
        }),
        new uglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
    ]
}

注意加载顺序,要把通用模块放在前面

<html>
  <body>
    <div id="a"></div>
    <div id="b"></div>
    <script src="init.js"></script>
    <script src="bundle1.js"></script>
    <script src="bundle2.js"></script>
  </body>
</html>

两个bundle文件中都包含init

Vendor chunk

抽第三方库,并设置为变量,拿jquery举例。比如:

// main.js
$('h1').text('Hello World');
$('h1').css('color','red');
// webpack.config.js
var webpack = require('webpack');
module.exports = {
  entry: {
    app: './main.js',
    vendor: ['jquery'],
  },
  output: {
    filename: 'bundle.js'
  },
  plugins: [
      new webpack.optimize.CommonsChunkPlugin({
          name:'vendor',
          filename:'vendor.js'
      }),
      new webpack.ProvidePlugin({ 
          $: 'jquery',//在这里设置一个变量
          jQuery: 'jquery'
      })
  ]
};

// 省略部分代码
// 要先引入vendor.js
<script src="vendor.js"></script>
<script src="bundle.js"></script>

Exposing global variables

如果想引入某些模块,但不想被webpack预加载且依然可以通过CMD、AMD或者window/global全局的方式访问。

比如,想要全局引入data.js,但不想被编译到bundle中

// data.js
var data = 'Hello World';
// webpack.config.js
module.exports = {
  entry: './main.jsx',
  output: {
    filename: 'bundle.js'
  },
  module: {
    loaders:[
      { test: /\.js[x]?$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' },
    ]
  },
  externals: {
    'data2': 'data' //data2为注册的全局变量
  }
};
// main.js
var data2 = require('data2'); //直接require就可以了
var React = require('react');
var ReactDOM = require('react-dom');
var $ = require("jquery");

ReactDOM.render(
  <h1>{data2}</h1>,
  document.body
);

Hot Module Replacement

热更新是在应用程序运行时不进行页面重新加载的情况下交换,添加或删除模块。
亲测webpack2只要wds就可以实现热更新了,以下配置适用于wepack1
两种方法

  1. 命令行
$ webpack-dev-server --hot --inline

2.修改webpack.config.js

var webpack = require('webpack');
var path = require('path');

module.exports = {
  entry: [
    'webpack/hot/dev-server',
    'webpack-dev-server/client?http://localhost:8080',
    './index.js'
  ],
  output: {
    filename: 'bundle.js',
    publicPath: '/static/'
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ],
  module: {
    loaders: [{
      test: /\.jsx?$/,
      loaders: ['babel-loader?presets[]=es2015&presets[]=react'],
      include: path.join(__dirname, '.')
    }]
  }
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容