zoukankan      html  css  js  c++  java
  • webpack入门(2)

    webpack入门(2)

    ps:每个案例都是基于前一个案例改造的

    webpack入门(1) 戳这里

    案例源码戳这里




    十二、ProvidePlugin

    自动加载模块

    new webpack.ProvidePlugin()

    上面的案例太复杂,下面再新建一个简单的项目来讲解




    案例16 -- 全局引入jquery

    新建一个项目,如下

    [webpack]
      |-- src
        |-- index.html
        |-- index.less
        |-- index.js
      |-- package.json
      |-- webpack.config.js
    

    webpack/package.json

    {
      "name": "webpack",
      "version": "1.0.0",
      "description": "",
      "scripts": {
        "start": "webpack-dev-server --content-base build --inline --hot",
        "build": "webpack -p",
        "test": "echo "Error: no test specified" && exit 1"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.2",
        "babel-preset-es2015": "^6.24.1",
        "css-loader": "^0.28.7",
        "extract-text-webpack-plugin": "^3.0.2",
        "file-loader": "^1.1.5",
        "html-webpack-plugin": "^2.30.1",
        "jquery": "^3.2.1",
        "less": "^2.7.3",
        "less-loader": "^4.0.5",
        "style-loader": "^0.19.0",
        "url-loader": "^0.6.2",
        "webpack": "^3.10.0",
        "webpack-dev-server": "^2.9.5"
      }
    }
    

    webpack/webpack.config.js

    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    module.exports = {
      entry: { // 入口文件地址
        index: './src/index.js',
        jquery: [ "jquery" ]
      },
      output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: '[name].js' // 文件名,name即为entry的key
      },
      module: {
        loaders: [
          {
            test: /.js$/,  // js-loader
            loader: 'babel-loader?presets=es2015'
          },
          {
            test: /.css$/, // css-loader
            loader: ExtractTextPlugin.extract('css-loader')
          },
          {
            test: /.less/, // less-loader
            loaders: ExtractTextPlugin.extract('css-loader!less-loader')
          },
          {
            test: /.(png|jpg)$/, // img-loader
            loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
          }
        ],
      },
      plugins: [
        new HtmlWebpackPlugin({
          filename: 'index.html', // 生成的的html文件名
          template: './src/index.html', // 被打包的html路径
          chunks: ['index', 'jquery'] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({ // 单独打包css
          filename: '[name].css'
        }),
        new webpack.optimize.CommonsChunkPlugin({
          name: 'jquery' // 对应entry的key
        }),
        new webpack.ProvidePlugin({ // 全局引入jquery
          $: 'jquery'
        })
      ]
    }
    

    webpack/src/index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>webpackDemo</title>
    </head>
    <body>
      
    </body>
    </html>
    

    webpack/src/index.less

    body {
      background: lightpink;
    }
    

    webpack/src/index.js

    import './index.less';
    $('body').prepend('hi');
    

    在webpack.config.js里设置了全局引入jquery,这里就不需要

    import $ from 'jquery'
    

    可以直接用 $

    $ npm run start , 打开 http://localhost:8080/index.html , 效果如下

    39




    十三、iconfont

    点击这里下载 案例17 使用的iconfont文件,以下简称“案例17压缩包”




    案例17

    新增文件 iconfont.less 和 iconfont.ttf(案例17压缩包里的iconfont.ttf),将index.less移动至css文件夹下,如下

    [webpack]
      |-- src
        |-- images
          |-- iconfont.ttf
        |-- css
          |-- iconfont.less
          |-- index.less
        |-- index.html
        |-- index.js
      |-- package.json
      |-- webpack.config.js
    

    webpack/src/css/iconfont.less

    @font-face {
      font-family: "iconfont";
      src: url('../images/iconfont.ttf') format('truetype');
    }
    .iconfont {
      font-family: "iconfont" !important;
      font-size: 16px;
      font-style: normal;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    .icon-love:before { content: "e612"; }
    

    webpack/src/css/index.less

    @import './iconfont.less';
    body {
      background: lightpink;
      .iconfont {
        font-size: 50px;
      }
    }
    

    webpack/src/index.js

    import './css/index.less';
    $('body').prepend('<i class="iconfont icon-love"></i>');
    

    webpack/webpack.config.js

    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    module.exports = {
      entry: { // 入口文件地址
        index: './src/index.js',
        jquery: [ "jquery" ]
      },
      output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: '[name].js' // 文件名,name即为entry的key
      },
      module: {
        loaders: [
          {
            test: /.js$/,  // js-loader
            loader: 'babel-loader?presets=es2015'
          },
          {
            test: /.css$/, // css-loader
            loader: ExtractTextPlugin.extract('css-loader')
          },
          {
            test: /.less/, // less-loader
            loaders: ExtractTextPlugin.extract('css-loader!less-loader')
          },
          {
            test: /.(png|jpg|ttf)$/, // img-loader
            loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
          }
        ],
      },
      plugins: [
        new HtmlWebpackPlugin({
          filename: 'index.html', // 生成的的html文件名
          template: './src/index.html', // 被打包的html路径
          chunks: ['index', 'jquery'] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({ // 单独打包css
          filename: '[name].css'
        }),
        new webpack.optimize.CommonsChunkPlugin({
          name: 'jquery' // 对应entry的key
        }),
        new webpack.ProvidePlugin({ // 全局引入jquery
          $: 'jquery'
        })
      ]
    }
    

    本案例只引入了ttf,其他可以类似添加

    {
      test: /.(png|jpg|ttf|svg|eot|woff)$/, // img-loader
      loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
    }
    

    $ npm run start , 打开 http://localhost:8080/index.html ,效果如下

    40

    $ npm run build , iconfont.ttf文件小会转为base64直接打包到index.css里,如果文件比较大,则会单独打包到webpack/build/images/iconfont.ttf




    十四、externals

    externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。

    比如 jquery 希望通过 cdn 的方式引入,代码里依旧用 import 的方式来使用,但是又不希望被打包。




    案例18

    webpack/src/index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>webpackDemo</title>
    </head>
    <body>
      <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
    </body>
    </html>
    

    webpack/src/index.js

    import $ from 'jquery';
    import './css/index.less';
    $('body').prepend('<i class="iconfont icon-love"></i>');
    

    webpack/webpack.config.js

    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    module.exports = {
      entry: { // 入口文件地址
        index: './src/index.js'
      },
      output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: '[name].js' // 文件名,name即为entry的key
      },
      externals: {
        jquery: 'jQuery' // jquery不被webpack编译到文件中
      },
      module: {
        loaders: [
          {
            test: /.js$/,  // js-loader
            loader: 'babel-loader?presets=es2015'
          },
          {
            test: /.css$/, // css-loader
            loader: ExtractTextPlugin.extract('css-loader')
          },
          {
            test: /.less/, // less-loader
            loaders: ExtractTextPlugin.extract('css-loader!less-loader')
          },
          {
            test: /.(png|jpg|ttf)$/, // img-loader
            loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
          }
        ],
      },
      plugins: [
        new HtmlWebpackPlugin({
          filename: 'index.html', // 生成的的html文件名
          template: './src/index.html', // 被打包的html路径
          chunks: ['index'] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({ // 单独打包css
          filename: '[name].css'
        })
      ]
    }
    

    运行 $ npm run build , 生成文件目录如下

    [webpack]
      |-- build
        |-- index.css
        |-- index.html
        |-- index.js
    



    十五、react

    安装依赖
    $ npm i babel-preset-react react react-dom --save-dev




    案例19

    webpack/src/index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>webpackDemo</title>
    </head>
    <body>
      <div id="root"></div>
    </body>
    </html>
    

    webpack/src/index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './css/index.less';
    
    class Demo extends React.Component {
      render() {
        return (
          <i  className="iconfont icon-love" />
        );
      }
    }
    
    ReactDOM.render(
      <Demo />,
      document.getElementById('root')
    );
    

    webpack/webpack.config.js

    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    module.exports = {
      entry: { // 入口文件地址
        index: './src/index.js'
      },
      output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: '[name].js' // 文件名,name即为entry的key
      },
      module: {
        loaders: [
          {
            test: /.(js|jsx)$/,  // js-loader
            loader: 'babel-loader?presets[]=es2015&presets[]=react'
          },
          {
            test: /.css$/, // css-loader
            loader: ExtractTextPlugin.extract('css-loader')
          },
          {
            test: /.less/, // less-loader
            loaders: ExtractTextPlugin.extract('css-loader!less-loader')
          },
          {
            test: /.(png|jpg|ttf)$/, // img-loader
            loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
          }
        ],
      },
      plugins: [
        new HtmlWebpackPlugin({
          filename: 'index.html', // 生成的的html文件名
          template: './src/index.html', // 被打包的html路径
          chunks: ['index'] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({ // 单独打包css
          filename: '[name].css'
        })
      ]
    }
    

    需要babel-preset-react插件来编译React

    运行 $ npm run start , 打开 http://localhost:8080/ ,能看到效果

    运行 $ npm run build ,打包文件目录如下:

    [webpack]
      |-- build
        |-- index.css
        |-- index.html
        |-- index.js
    

    react被打包到webpack/build/index.js里去了




    案例20 -- react 通过 cdn 的方式引入

    webpack/src/index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>webpackDemo</title>
    </head>
    <body>
      <div id="root"></div>
      <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
      <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    </body>
    </html>
    

    webpack/webpack.config.js

    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    module.exports = {
      entry: { // 入口文件地址
        index: './src/index.js'
      },
      output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: '[name].js' // 文件名,name即为entry的key
      },
      externals: {
        'react': 'React',
        'react-dom': 'ReactDOM'
      },
      module: {
        loaders: [
          {
            test: /.(js|jsx)$/,  // js-loader
            loader: 'babel-loader?presets[]=es2015&presets[]=react'
          },
          {
            test: /.css$/, // css-loader
            loader: ExtractTextPlugin.extract('css-loader')
          },
          {
            test: /.less/, // less-loader
            loaders: ExtractTextPlugin.extract('css-loader!less-loader')
          },
          {
            test: /.(png|jpg|ttf)$/, // img-loader
            loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
          }
        ],
      },
      plugins: [
        new HtmlWebpackPlugin({
          filename: 'index.html', // 生成的的html文件名
          template: './src/index.html', // 被打包的html路径
          chunks: ['index'] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({ // 单独打包css
          filename: '[name].css'
        })
      ]
    }
    

    这样 react 就不会被打包入 webpack/build/index.js




    十六、devServer

    • hot : boolean , 启用 webpack 的模块热替换特性
    • inline : boolean , 内联模式(默认) , false 时为 iframe 模式
    • contentBase : boolean|string|array , 设定webpack-dev-server的director根目录。如果不进行设定的话,默认是在当前目录下。
    • compress : boolean , 一切服务都启用 gzip 压缩
    • port : number , 指定要监听请求的端口号
    • host : string , 指定使用一个 host
    • proxy : object , webpack 代理
    • filename : string , 可以只在某个文件时被请求时编译
    • headers : object , 在所有请求中添加首部内容

    更多参数戳这里




    案例21

    新建一个项目如下

    [webpack]
      |-- package.json
      |-- webpack.config.js
      |-- src
        |-- index.html
        |-- index.js
        |-- images
          |-- SpongeBob.jpg
        |-- css
          |-- index.less
    

    本案例用到的图片 SpongeBob.jpg 戳这里

    webpack/package.json

    {
      "name": "webpack",
      "version": "1.0.0",
      "description": "",
      "scripts": {
        "start": "webpack-dev-server",
        "build": "webpack -p"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.2",
        "babel-preset-es2015": "^6.24.1",
        "babel-preset-react": "^6.24.1",
        "css-loader": "^0.28.7",
        "extract-text-webpack-plugin": "^3.0.2",
        "file-loader": "^1.1.5",
        "html-webpack-plugin": "^2.30.1",
        "jquery": "^3.2.1",
        "less": "^2.7.3",
        "less-loader": "^4.0.5",
        "style-loader": "^0.19.0",
        "url-loader": "^0.6.2",
        "webpack": "^3.10.0",
        "webpack-dev-server": "^2.9.5"
      }
    }
    

    webpack/webpack.config.js

    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    module.exports = {
      entry: { // 入口文件地址
        index: './src/index.js'
      },
      output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: '[name].js' // 文件名,name即为entry的key
      },
      externals: {
        'jquery': 'jQuery', // 不打包jquery
      },
      module: {
        loaders: [
          {
            test: /.(js|jsx)$/,  // js-loader
            loader: 'babel-loader?presets[]=es2015&presets[]=react'
          },
          {
            test: /.less/, // less-loader
            loaders: ExtractTextPlugin.extract('css-loader!less-loader')
          },
          {
            test: /.(png|jpg|ttf)$/, // img-loader
            loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
          }
        ],
      },
      devServer: {
        contentBase: './build',
        inline: true,
        hot: true
      },
      plugins: [
        new webpack.HotModuleReplacementPlugin(), // 启用热替换模块
        new HtmlWebpackPlugin({
          filename: 'index.html', // 生成的的html文件名
          template: './src/index.html', // 被打包的html路径
          chunks: ['index'] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({ // 单独打包css
          filename: '[name].css'
        })
      ]
    }
    

    webpack/src/index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>webpackDemo</title>
    </head>
    <body>
      <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
    </body>
    </html>
    

    webpack/src/css/index.less

    body {
      background: url(../images/SpongeBob.jpg) no-repeat;
      color: blue;
    }
    

    webpack/src/index.js

    import './css/index.less';
    
    $('body').prepend('hi')
    

    package.json 对比

    // 案例16
    "scripts": {
      "start": "webpack-dev-server --content-base build --inline --hot",
    }
    // 案例21
    "scripts": {
      "start": "webpack-dev-server",
    }
    

    案例21 中 webpack-dev-server 后的参数,改为在 webapck.config.js 中设置

    {
      devServer: {
        contentBase: './build',
        inline: true,
        hot: true
      },
      plugins: [ new webpack.HotModuleReplacementPlugin() ]
    }
    

    $ npm run start , 打开 http://localhost:8080/ , 效果如下

    41




    十七、本地 mock 模拟后端数据

    {
      devServer: {
        before: (app) =>{
          app.get('/init.json', function(req, res) {
            res.json({ title: 'webpack' });
          });
        }
      }
    }
    



    案例22

    webpack/webpack.config.js

    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    module.exports = {
      entry: { // 入口文件地址
        index: './src/index.js'
      },
      output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: '[name].js' // 文件名,name即为entry的key
      },
      externals: {
        'jquery': 'jQuery', // 不打包jquery
      },
      module: {
        loaders: [
          {
            test: /.(js|jsx)$/,  // js-loader
            loader: 'babel-loader?presets[]=es2015&presets[]=react'
          },
          {
            test: /.less/, // less-loader
            loaders: ExtractTextPlugin.extract('css-loader!less-loader')
          },
          {
            test: /.(png|jpg|ttf)$/, // img-loader
            loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
          }
        ],
      },
      devServer: {
        contentBase: './build',
        inline: true,
        hot: true,
        before: (app) =>{
          app.get('/init.json', function(req, res) {
            res.json({ title: 'webpack' });
          });
        }
      },
      plugins: [
        new webpack.HotModuleReplacementPlugin(), // 启用热替换模块
        new HtmlWebpackPlugin({
          filename: 'index.html', // 生成的的html文件名
          template: './src/index.html', // 被打包的html路径
          chunks: ['index'] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({ // 单独打包css
          filename: '[name].css'
        })
      ]
    }
    

    webpack/src/index.js

    import './css/index.less';
    
    $.ajax({
      url: '/init.json',
      data: {},
      type: 'GET',
      success: (d = {}) => {
        $('body').prepend(d.title);
      },
      error: () => {
        $('body').prepend('ajax error');
      }
    });
    

    $ npm run start , 打开 http://localhost:8080/index.html , 效果如下

    42

    如果是 post 请求,webpack.config.js 如下

    {
      devServer: {
        before: (app) =>{
          app.post('/init.json', function(req, res) {
            res.json({ title: 'webpack' });
          });
        }
      }
    }
    

    当然,也可以不在 res.json() 中直接写 mock 数据,可以在外面命名变量,或者从其他文件引入

    var mock_init = require('xxxxx');
    var mock_user = { title: 'webpack' };
    module.exports = {
      devServer: {
        before: (app) =>{
          app.post('/init.json', function(req, res) {
            res.json(mock_init);
          });
          app.post('/user.json', function(req, res) {
            res.json(mock_user);
          });
        }
      }
    }
    



    十八、环境变量

    DefinePlugin 可以把命令行的环境变量带到浏览器端。

    new webpack.DefinePlugin()
    

    详解戳这里




    案例23

    环境变量在很多情况都会使用,这里举一个例子,比如我们本地 mock 数据时,请求都是 "localhost:8080" 开头的,但是到线上了则是 "http://a.com" 和 "http://b.com" , 这个时候就可以使用 DefinePlugin 来解决

    webpack/package.json

    {
      "name": "webpack",
      "version": "1.0.0",
      "description": "",
      "scripts": {
        "start": "NODE_ENV=mock webpack-dev-server",
        "prod": "NODE_ENV=prod webpack-dev-server",
        "build-start": "NODE_ENV=mock webpack -p",
        "build-prod": "NODE_ENV=prod webpack -p"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.2",
        "babel-preset-es2015": "^6.24.1",
        "babel-preset-react": "^6.24.1",
        "css-loader": "^0.28.7",
        "extract-text-webpack-plugin": "^3.0.2",
        "file-loader": "^1.1.5",
        "html-webpack-plugin": "^2.30.1",
        "jquery": "^3.2.1",
        "less": "^2.7.3",
        "less-loader": "^4.0.5",
        "style-loader": "^0.19.0",
        "url-loader": "^0.6.2",
        "webpack": "^3.10.0",
        "webpack-dev-server": "^2.9.5"
      }
    }
    

    "NODE_ENV=xxx" , 可以定义不同环境的 NODE_ENV

    start 和 build-start , 是我们本地开发时使用 ; prod 和 build-prod , 是线上环境使用

    webpack/webpack.config.js

    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    console.log('----------- NODE_ENV ----------- : ', process.env.NODE_ENV)
    
    module.exports = {
      entry: { // 入口文件地址
        index: './src/index.js'
      },
      output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: '[name].js' // 文件名,name即为entry的key
      },
      externals: {
        'jquery': 'jQuery', // 不打包jquery
      },
      module: {
        loaders: [
          {
            test: /.(js|jsx)$/,  // js-loader
            loader: 'babel-loader?presets[]=es2015&presets[]=react'
          },
          {
            test: /.less/, // less-loader
            loaders: ExtractTextPlugin.extract('css-loader!less-loader')
          },
          {
            test: /.(png|jpg|ttf)$/, // img-loader
            loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
          }
        ],
      },
      devServer: {
        contentBase: './build',
        inline: true,
        hot: true,
        before: (app) =>{
          app.get('/init.json', function(req, res) {
            res.json({ title: 'webpack' });
          });
        }
      },
      plugins: [
        new webpack.HotModuleReplacementPlugin(), // 启用热替换模块
        new HtmlWebpackPlugin({
          filename: 'index.html', // 生成的的html文件名
          template: './src/index.html', // 被打包的html路径
          chunks: ['index'] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({ // 单独打包css
          filename: '[name].css'
        })
      ]
    }
    

    通过 process.env.NODE_ENV 变量拿到值

    $ npm run start , 效果如下

    43

    $ npm run prod , 效果如下

    44

    webpack/webpack.config.js

    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    const checkHost = {
      "mock": {
        "A_HOST": "http://localhost:8080",
        "B_HOST": "http://localhost:8080",
      },
      "prod": {
        "A_HOST": "http://a.com",
        "B_HOST": "http://b.com",
      }
    }
    
    var checkHostKey = checkHost[process.env.NODE_ENV] ? process.env.NODE_ENV : 'mock';
    
    var checkHostContent = checkHost[checkHostKey];
    
    for (i in checkHostContent) {
      checkHostContent[i] = JSON.stringify(checkHostContent[i]);
    }
    
    module.exports = {
      entry: { // 入口文件地址
        index: './src/index.js'
      },
      output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: '[name].js' // 文件名,name即为entry的key
      },
      externals: {
        'jquery': 'jQuery', // 不打包jquery
      },
      module: {
        loaders: [
          {
            test: /.(js|jsx)$/,  // js-loader
            loader: 'babel-loader?presets[]=es2015&presets[]=react'
          },
          {
            test: /.less/, // less-loader
            loaders: ExtractTextPlugin.extract('css-loader!less-loader')
          },
          {
            test: /.(png|jpg|ttf)$/, // img-loader
            loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
          }
        ],
      },
      devServer: {
        contentBase: './build',
        inline: true,
        hot: true,
        before: (app) =>{
          app.get('/init.json', function(req, res) {
            res.json({ title: 'webpack' });
          });
        }
      },
      plugins: [
        new webpack.DefinePlugin(checkHostContent),
        new webpack.HotModuleReplacementPlugin(), // 启用热替换模块
        new HtmlWebpackPlugin({
          filename: 'index.html', // 生成的的html文件名
          template: './src/index.html', // 被打包的html路径
          chunks: ['index'] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({ // 单独打包css
          filename: '[name].css'
        })
      ]
    }
    

    分析如下

    const checkHost = {
      "mock": { // 本地 mock 数据使用
        "A_HOST": "http://localhost:8080",
        "B_HOST": "http://localhost:8080",
      },
      "prod": { // 线上环境使用
        "A_HOST": "http://a.com",
        "B_HOST": "http://b.com",
      }
    }
    
    // 检查 checkHost[process.env.NODE_ENV] 是否存在,不存在时,将rocess.env.NODE_ENV 设置为 mock
    var checkHostKey = checkHost[process.env.NODE_ENV] ? process.env.NODE_ENV : 'mock';
    
    // checkHostContent 相当于是 checkHost.mock 或 checkHost.prod
    var checkHostContent = checkHost[checkHostKey];
    
    // 如果 DefinePlugin 键值是一个字符串,它会被当作一个代码片段来使用,需要 JSON.stringify() 处理
    for (i in checkHostContent) {
      checkHostContent[i] = JSON.stringify(checkHostContent[i]);
    }
    
    // 将处理好的 checkHostContent 放入
    module.exports = {
      plugins: [new webpack.DefinePlugin(checkHostContent)]
    }
    

    这一部分代码,将我们要用到的 A_HOST 和 B_HOST 都处理好,再放入new webpack.DefinePlugin(),拿 prod 举例,相当于处理成

    module.exports = {
      plugins: [new webpack.DefinePlugin({
        A_HOST: JSON.stringify("http://a.com"),
        B_HOST: JSON.stringify("http://b.com"),
      })]
    }
    

    webpack/src/index.js

    import './css/index.less';
    
    console.log(A_HOST, B_HOST)
    
    $.ajax({
      url: `${A_HOST}/init.json`,
      data: {},
      type: 'GET',
      success: (d = {}) => {
        $('body').prepend(d.title);
      },
      error: () => {
        $('body').prepend('ajax error');
      }
    });
    

    $ npm run start , 效果如下

    45

    $ npm run prod , 效果如下

    46

    当然,也可以直接写两个 webpack.config.js 文件,这里就贴一下代码,不具体写案例了

    // webpack.start.config.js
    module.exports = {
      plugins: [new webpack.DefinePlugin({
        A_HOST: JSON.stringify("http://localhost:8080"),
        B_HOST: JSON.stringify("http://localhost:8080"),
      })]
    }
    
    // webpack.prod.config.js
    module.exports = {
      plugins: [new webpack.DefinePlugin({
        A_HOST: JSON.stringify("http://a.com"),
        B_HOST: JSON.stringify("http://b.com"),
      })]
    }
    
    // package.json
    {
      "scripts": {
        "start": "webpack-dev-server --config webpack.start.config.js",
        "prod": "webpack-dev-server --config webpack.prod.config.js",
        "build-start": "webpack -p --config webpack.start.config.js",
        "build-prod": "webpack -p --config webpack.prod.config.js"
      }
    }
    



    十九、server.js

    详细介绍戳这里




    案例24

    新增 webpack/server.js , 目录如下

    [webpack]
      |-- server.js
      |-- package.json
      |-- webpack.config.js
      |-- src
        |-- index.html
        |-- index.js
        |-- images
          |-- SpongeBob.jpg
        |-- css
          |-- index.less
    

    webpack/webpack.config.js

    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    const checkHost = {
      "mock": { // 本地 mock 数据使用
        "A_HOST": "http://localhost:8080",
        "B_HOST": "http://localhost:8080",
      },
      "prod": { // 线上环境使用
        "A_HOST": "http://a.com",
        "B_HOST": "http://b.com",
      }
    }
    
    // 检查 process.env.NODE_ENV 是否和 checkHost 里的对应
    var checkHostKey = checkHost[process.env.NODE_ENV] ? process.env.NODE_ENV : 'mock';
    
    // checkHostContent 相当于是 checkHost.mock 或 checkHost.prod
    var checkHostContent = checkHost[checkHostKey];
    
    // 如果 DefinePlugin 键值是是一个字符串,它会被当作一个代码片段来使用,需要 JSON.stringify() 处理
    for (i in checkHostContent) {
      checkHostContent[i] = JSON.stringify(checkHostContent[i]);
    }
    
    module.exports = {
      entry: { // 入口文件地址
        index: ['./src/index.js']
      },
      output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: '[name].js' // 文件名,name即为entry的key
      },
      externals: {
        'jquery': 'jQuery', // 不打包jquery
      },
      module: {
        loaders: [
          {
            test: /.(js|jsx)$/,  // js-loader
            loader: 'babel-loader?presets[]=es2015&presets[]=react'
          },
          {
            test: /.less/, // less-loader
            loaders: ExtractTextPlugin.extract('css-loader!less-loader')
          },
          {
            test: /.(png|jpg|ttf)$/, // img-loader
            loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
          }
        ],
      },
      plugins: [
        new webpack.DefinePlugin(checkHostContent), // 将处理好的 checkHostContent 放入
        new webpack.HotModuleReplacementPlugin(), // 启用热替换模块
        new HtmlWebpackPlugin({
          filename: 'index.html', // 生成的的html文件名
          template: './src/index.html', // 被打包的html路径
          chunks: ['index'] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({ // 单独打包css
          filename: '[name].css'
        })
      ]
    }
    

    将 devServer 删除 , entry.index 改为 array 写法

    webpack/server.js

    // 引入 webpack 和 webpack-dev-server
    var webpack = require('webpack');
    var WebpackDevServer = require('webpack-dev-server');
    
    // 引入 webpack 的配置
    var config = require('./webpack.config.js');
    
    // 添加 webpack-dev-server 的客户端入口文件到 webpack 的配置中
    // 通过 unshift 方法,将 webpack-dev-server/client?http://«path»:«port»/ 插入到 webpack-dev-server 配置的 entry.index 中
    config.entry.index.unshift("webpack-dev-server/client?http://localhost:8080/");
    
    // compiler = webpack({ webpack 的配置 })
    var compiler = webpack(config);
    
    // server = new WebpackDevServer(compiler, { devServer 的配置 })
    var server = new WebpackDevServer(compiler, {
      contentBase: './build',
      inline: true,
      hot: true,
      before: (app) =>{
        app.get('/init.json', function(req, res) {
          res.json({ title: 'webpack' });
        });
      }
    });
    
    server.listen(8080, "localhost", function() {});
    

    webpack-dev-server 的配置里没有 inline : true 这个配置项, 因为 webpack-dev-server 无法访问 webpack 的配置。 因此,用户必须添加 webpack-dev-server 的客户端入口文件到 webpack 的配置中,有以下几种方式(上面案例只写了一种,其他大家可以自行尝试)

    // server.js
    config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/");
    
    // webpack.config.js
    {
      entry: {
        index: [
         'webpack-dev-server/client?http://localhost:8080/',
         './src/index.js'
        ]
      }
    }
    // index.html
    <script src="http://localhost:8080/webpack-dev-server.js"></script>
    

    webpack/package.json

    {
      "name": "webpack",
      "version": "1.0.0",
      "description": "",
      "scripts": {
        "start": "NODE_ENV=mock node server.js",
        "prod": "NODE_ENV=prod node server.js",
        "build-start": "NODE_ENV=mock webpack -p",
        "build-prod": "NODE_ENV=prod webpack -p"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.2",
        "babel-preset-es2015": "^6.24.1",
        "babel-preset-react": "^6.24.1",
        "css-loader": "^0.28.7",
        "extract-text-webpack-plugin": "^3.0.2",
        "file-loader": "^1.1.5",
        "html-webpack-plugin": "^2.30.1",
        "jquery": "^3.2.1",
        "less": "^2.7.3",
        "less-loader": "^4.0.5",
        "style-loader": "^0.19.0",
        "url-loader": "^0.6.2",
        "webpack": "^3.10.0",
        "webpack-dev-server": "^2.9.5"
      }
    }
    

    修改了 scripts.start 和 scripts.prod ,$ npm run start 和 $ npm run prod ,效果和 案例23 一样




    二十、module.rules

    下面介绍一下 loaders 的其他写法




    案例25

    webpack/server.js

    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    const checkHost = {
      "mock": { // 本地 mock 数据使用
        "A_HOST": "http://localhost:8080",
        "B_HOST": "http://localhost:8080",
      },
      "prod": { // 线上环境使用
        "A_HOST": "http://a.com",
        "B_HOST": "http://b.com",
      }
    }
    
    // 检查 process.env.NODE_ENV 是否和 checkHost 里的对应
    var checkHostKey = checkHost[process.env.NODE_ENV] ? process.env.NODE_ENV : 'mock';
    
    // checkHostContent 相当于是 checkHost.mock 或 checkHost.prod
    var checkHostContent = checkHost[checkHostKey];
    
    // 如果 DefinePlugin 键值是是一个字符串,它会被当作一个代码片段来使用,需要 JSON.stringify() 处理
    for (i in checkHostContent) {
      checkHostContent[i] = JSON.stringify(checkHostContent[i]);
    }
    
    module.exports = {
      entry: { // 入口文件地址
        index: ['./src/index.js']
      },
      output: { // 出口
        path: __dirname + "/build", // 打包后的文件存放路径
        filename: '[name].js' // 文件名,name即为entry的key
      },
      externals: {
        'jquery': 'jQuery', // 不打包jquery
      },
      module: {
        rules: [ // loaders
          {
            test: /.(js|jsx)$/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: ['es2015', 'react']
              }
            }
          },
          {
            test: /.less$/,
            use: ExtractTextPlugin.extract({
              use: [{
                loader: "css-loader"
              }, {
                loader: "less-loader"
              }]
            })
          },
          {
            test: /.(png|jpg|ttf)$/,
            use: [
              {
                loader: 'url-loader',
                options: {
                  limit: 8192,
                  name: 'images/[hash:8].[name].[ext]'
                }
              }
            ]
          }
        ]
      },
      plugins: [
        new webpack.DefinePlugin(checkHostContent), // 将处理好的 checkHostContent 放入
        new webpack.HotModuleReplacementPlugin(), // 启用热替换模块
        new HtmlWebpackPlugin({
          filename: 'index.html', // 生成的的html文件名
          template: './src/index.html', // 被打包的html路径
          chunks: ['index'] // 需要引入的js,对应entry的key
        }),
        new ExtractTextPlugin({ // 单独打包css
          filename: '[name].css'
        })
      ]
    }
    

    对比分析如下

    {
      module: {
        // module.loaders 改为 module.rules
        rules: [
          // {
          //   test: /.(js|jsx)$/,  // js-loader
          //   loader: 'babel-loader?presets[]=es2015&presets[]=react'
          // }
          {
            test: /.(js|jsx)$/,
            use: {
              loader: 'babel-loader',
              options: { // ? 后的参数可以写在这里
                presets: ['es2015', 'react']
              }
            }
          },
          // {
          //   test: /.less/, // less-loader
          //   loaders: ExtractTextPlugin.extract('css-loader!less-loader')
          // }
          {
            test: /.less$/,
            use: ExtractTextPlugin.extract({
              use: [{
                loader: "css-loader"
              }, {
                loader: "less-loader"
              }]
            })
          },
          // {
          //   test: /.(png|jpg|ttf)$/, // img-loader
          //   loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
          // }
          {
            test: /.(png|jpg|ttf)$/,
            use: [
              {
                loader: 'url-loader',
                options: {
                  limit: 8192,
                  name: 'images/[hash:8].[name].[ext]'
                }
              }
            ]
          }
        ]
      }
    }
    
  • 相关阅读:
    鱼眼相机畸变矫正资料
    异常值检测算法三:3sigma模型
    五:瑞芯微RV1109
    四:海思Hi3516CV500/Hi3516DV300
    三:瑞芯微OK3399-C开发板
    二:飞凌嵌入式FCU1201
    一:芯片概述
    六:大数据架构
    五:大数据架构回顾-LambdaPlus架构
    四:大数据架构回顾-IOTA架构
  • 原文地址:https://www.cnblogs.com/sakurayeah/p/8109978.html
Copyright © 2011-2022 走看看