Webpack的使用

1、安裝:在全局環境下安裝css

$ npm i -g webpack webpack-dev-server

2、運行命令,若是不能自動打開網頁,在瀏覽器的地址欄輸入:http://127.0.0.1:8080html

npm run dev

webpack是爲瀏覽器構建JavaScript模塊腳本的quan前端工具。它能夠相似於Browserify同樣,可是能作的更多。前端

$ browserify main.js > bundle.js
# be equivalent to
$ webpack main.js bundle.js

Webpack須要一個配置文件名叫webpack.config.js,是一個commonJS的模塊。有了這個文件以後,能夠調用webpack,不須要別的參數。一些經常使用的命令行:node

webpack – building for development
webpack -p – building for production (minification)
webpack --watch – for continuous incremental building
webpack -d – including source maps
webpack --colors – making building output pretty

能夠在package.json文件中對這些命令作個性化處理。react

"scripts": {
    "dev": "webpack-dev-server --open",
    "build": "webpack -p"
  },

執行 npm run dev 就是執行 webpack-dev-server --open,npm run build就是執行webpack -p。jquery

3、入口文件:是webpack用來讀取以建立bundle.js的文件。Webpack根據webpack.config.js建立bundle.js。webpack.config.js代碼以下:webpack

module.exports = {
  entry: './main.js',    // main.js是入口文件
  output: {
    filename: 'bundle.js'
  }
};

 

4、多個入口文件:webpack.config.jsweb

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

5、babel 加載器npm

加載器是預處理程序,在webpack構建過程以前轉換應用程序的資源文件。例如,Bable-loader能夠將JSX/ES6文件轉換成正常的JS文件,以後Webpack開始構建這些JS文件。須要在webpack.config.js裏配置module。json

module.exports = {
  entry: './main.jsx',
  output: {
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015', 'react']   // 須要配置插件 babel-preset-es2015 和 babel-preset-react(安裝) 
          }
        }
      }
    ]
  }
};

題外話:提醒一下JSX的格式

// main.jsx
const React = require('react');
const ReactDOM = require('react-dom');

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.querySelector('#wrapper')
);

 

6、css加載器 css-loader

webpack能夠在JS文件中加載css文件,使用css-loader

webpack.config.js中的配置

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

須要兩個加載器:css-loader 和 style-loader(爲了向HTML代碼中插入<style>標籤)

 

7、Image loader

webpack.config.js代碼:

module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'
  },
  module: {
    rules:[
      {
        test: /\.(png|jpg)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192
            }
          }
        ]
      }
    ]
  }
};

main.js

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

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

url-loader會把圖片類型的文件轉換到img標籤中,當圖片的大小小於limit的值,會轉換到data URL上??????

8、CSS Module

css-loader?modules 查詢參數模塊使CSS-modules提供了一個本地做用域的css,能夠用:global(selector)關閉。

app.css

/* local scope */
.h1 {
  color:red;
}

/* global scope */
:global(.h2) {
  color: blue;
}

9、UglifyJS 插件。webpack有本身的插件系統來拓展它的功能,UglifyJS能夠壓縮輸入文件bundle.js的JS代碼。

main.js

var longVariableName = 'Hello';
longVariableName += ' World';
document.write('<h1>' + longVariableName + '</h1>');

webpack.config.js

var webpack = require('webpack');
var UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'
  },
  plugins: [
    new UglifyJsPlugin()
  ]
};

最後main.js會被壓縮成:

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

10、HTML Webpack plugin 和 open browser webpack plugin

HTML Webpack plugin 能夠建立一個index.html文件,open browser webpack plugin能夠在webpack加載時打開一個新的瀏覽器標籤頁

11、environment flag

就好像是設置一個變量,只有設置了這個變量的環境才能夠訪問某些代碼,例如:

document.write('<h1>Hello World</h1>');

if (__DEV__) {
  document.write(new Date());
}

webpack.config.js

var webpack = require('webpack');

var devFlagPlugin = new webpack.DefinePlugin({
  __DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false'))
});

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

發現package.json有這樣的變化

{
  // ...
  "scripts": {
    "dev": "cross-env DEBUG=true webpack-dev-server --open",
  },
  // ...
}

12、code splitting

對於不少大型網站應用來講,把全部的代碼放在一個單獨的文件裏效率很低,webpack容許咱們把一個大型的JS文件分割成幾個塊,若是在某些狀況下只須要某些代碼塊,則能夠俺須要加載這些塊。webpack使用require.ensure來定義一個分割點。

main.js

require.ensure(['./a'], function (require) {
  var content = require('./a');
  document.open();
  document.write('<h1>' + content + '</h1>');
  document.close();
});

require.ensure告訴webpack ./a.js從bundle.js 分離了出來,創建了一個單獨的塊文件。webpack負責這些dependency,輸出文件,和運行時間等,不須要在index.html和webpack.config.js添加其餘的代碼。webpack實際上創建了兩個輸出文件,bundle.js 和 0.bundle.js。Webpack實際上將main.js 和 a.js構建爲不一樣的塊(bundle.js 和 0.bundle.js),並在須要時從bundle.js加載0.bundle.js。

另一種代碼分割的方式 使用bundle-loader。

// main.js

// Now a.js is requested, it will be bundled into another file
var load = require('bundle-loader!./a.js');

// To wait until a.js is available (and get the exports)
//  you need to async wait for it.
load(function(file) {
  document.open();
  document.write('<h1>' + file + '</h1>');
  document.close();
});

十3、common chunk

當多個JS文件擁有公共塊時,可使用插件CommonsChunkPlugin將公共部分提取到一個單獨的文件中,這有助於瀏覽器的緩存和節省帶寬。

這裏的代碼不是很理解,先粘貼過來,再研究吧??????

// main1.jsx
var React = require('react');
var ReactDOM = require('react-dom');

ReactDOM.render(
  <h1>Hello World</h1>,
  document.getElementById('a')
);

// main2.jsx
var React = require('react');
var ReactDOM = require('react-dom');

ReactDOM.render(
  <h2>Hello Webpack</h2>,
  document.getElementById('b')
);
<html>
  <body>
    <div id="a"></div>
    <div id="b"></div>
    <script src="commons.js"></script>
    <script src="bundle1.js"></script>
    <script src="bundle2.js"></script>
  </body>
</html>
var webpack = require('webpack');

module.exports = {
  entry: {
    bundle1: './main1.jsx',
    bundle2: './main2.jsx'
  },
  output: {
    filename: '[name].js'
  },
  module: {
    rules:[
      {
        test: /\.js[x]?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015', 'react']
          }
        }
      },
    ]
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: "commons",
      // (the commons chunk name)

      filename: "commons.js",
      // (the filename of the commons chunk)
    })
  ]
}

十4、Vendor clunk

能夠將腳本中的供應商庫從CommonsChunkPlugin中提取到單獨的文件中。

main.js

var $ = require('jquery');
$('h1').text('Hello World');

index.html

<html>
  <body>
    <h1></h1>
    <script src="vendor.js"></script>
    <script src="bundle.js"></script>
  </body>
</html>

webpack.config.js

var webpack = require('webpack');

module.exports = {
  entry: {
    app: './main.js',
    vendor: ['jquery'],    // jQuery包含在公共塊vendor.js
  },
  output: {
    filename: 'bundle.js'
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      filename: 'vendor.js'
    })
  ]
};

ProvidePlugin 插件可使一個變量在每一個模塊中像一個全局變量同樣使用,不須要從新import或者require。

// main.js
$('h1').text('Hello World');


// webpack.config.js
var webpack = require('webpack');

module.exports = {
  entry: {
    app: './main.js'
  },
  output: {
    filename: 'bundle.js'
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    })
  ]
};

十5、exposing global variables 公開全局變量

若是想使用一些全局變量,可是不想使他們包含在Webpack包裏,能夠在webpack.config.js中啓用external字段。

例如,新建一個data.js

// data.js
var data = 'Hello World';

index.html

<html>
  <body>
    <script src="data.js"></script>
    <script src="bundle.js"></script>
  </body>
</html>

可是此時,出口文件只有一個bundle.js 而不是data.js。data能夠做爲一個全局變量。

webpa.config.js

// webpack.config.js
module.exports = {
  entry: './main.jsx',
  output: {
    filename: 'bundle.js'
  },
  module: {
    rules:[
      {
        test: /\.js[x]?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015', 'react']
          }
        }
      },
    ]
  },
  externals: {
    // require('data') is external and available
    //  on the global var data
    'data': 'data'
  }
};

能夠在咱們的入口JS文件中使用這個全局變量。

// main.jsx
var data = require('data');
var React = require('react');
var ReactDOM = require('react-dom');

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

也能夠把react 和 react-dom 放入externals變量裏,方便減小bundle.js的建立時間和大小。

 

UglifyJs Plugin

相關文章
相關標籤/搜索