Webpack開發指南

前言

成爲一個全棧工程師,前端是必不可少的,這位前端構建工具webpack是一門必修的技術。javascript

在學習webpack以前,先熟悉一下npm工具:https://www.runoob.com/nodejs/nodejs-npm.htmlcss

什麼是webpack?html

webpack能夠打包全部的樣式,腳本,表,資源,生成一個或多個bundle,webpack 可以處理 JS 文件的互相依賴關係,可以處理JS的兼容問題,把高級的、瀏覽器不是別的語法,轉爲低級的瀏覽器能正常識別的語法。前端

 

官方文檔:https://www.webpackjs.com/concepts/java

example參考:https://github.com/lemonzoey/webpack-demo node

Hello Word

1  初始化項目  npm init , 建立src,dist目錄,在src下創建main.js,index.htmljquery

2 安裝依賴包jquery : npm install jquerywebpack

3 安裝webpack : npm install --save-dev webpackgit

mkdir webpack-study && cd webpack-study 
npm init -y
npm install webpack webpack-cli --save-dev

4 編寫項目github

main.js是項目的JS入口文件

// 這是 main.js 是咱們項目的JS入口文件

// 1. 導入 Jquery
// import *** from *** 是ES6中導入模塊的方式
// 因爲 ES6的代碼,過高級了,瀏覽器解析不了,因此,這一行執行會報錯
import $ from jquery
// const $ = require('jquery')

$(function () {
  $('li:odd').css('backgroundColor', 'yellow')
  $('li:even').css('backgroundColor', function () {
    return '#' + 'D97634'
  })
})

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <!-- 由於 main 中的代碼,涉及到了ES6的新語法,可是瀏覽器不識別 -->
    <!-- <script src="./main.js"></script> -->
    <!-- 經過 webpack 這麼一個前端構建工具, 把 main.js 作了一下處理,生成了一個 bundle.js 的文件 -->
     <script src="../dist/bundle.js"></script> 
</head>

<body>
    <ul>
        <li>這是第1個li</li>
        <li>這是第2個li</li>
        <li>這是第3個li</li>
        <li>這是第4個li</li>
        <li>這是第5個li</li>
        <li>這是第6個li</li>
        <li>這是第7個li</li>
        <li>這是第8個li</li>
        <li>這是第9個li</li>
        <li>這是第10個li</li>
    </ul>
</body>

</html>

5 webpack編譯打包main.js

   webpack src/main.js --output dist/bundle.js

 或者能夠在根目錄下建立 webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/main.js', //入口 表示要打包的文件
  output: {
    path: path.join(__dirname, './dist'),// 指定輸出路徑
    filename: 'my-first-webpack.bundle.js'
  }
};

再執行: webpack

固然執行命令能夠交給npm管理,須要在package.json上添加

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},

再執行命令   npm run build

 

資源管理

加載css樣式

1  安裝資源加載器   

npm install --save-dev style-loader css-loader

2 添加樣式文件

 

3  添加webpack配置文件css資源加載

const path = require('path');
module.exports = {
  entry: './src/main.js', //入口 表示要打包的文件
  output: {
    path: path.join(__dirname, './dist'),// 指定輸出路徑
    filename: 'bundle.js'
  },
  module:{
    rules:[
      {
        test:/\.css$/,
        use:[
          'style-loader',
          'css-loader'
        ]
      }
    ]
  }
};
View Code

4  修改main.js   添加css文件,使得資源文件被加載到bundle.js中

import './css/style.css'
 
效果圖

 

 

其餘加載圖片,字體,數據等資源,相同的操做步驟,可參考官方文檔.

 

輸出管理

HtmlWebpackPlugin

若是index.html中引用了多個bundle文件,若是這些bundle文件名稱發生改變,而index.html還引用原來的bundle文件名,則會出錯。

這個plugin就是讓指定的html每次build的時候生成一個新的html文件,該文件引用最新的bundle文件。

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
  entry: {  // 存在多個入口文件
    main: './src/main.js',
    print: './src/print.js'
  }, //入口 表示要打包的文件
  output: { // 也輸出多個bundle.js文件
    path: path.join(__dirname, './dist'),// 指定輸出路徑
    filename: '[name].bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'new Document'  // title=new Document的html文件,會從新加載生成一個新的html
    })
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      }
    ]
  }
};

clean-webpack-plugin

清理/dist 文件夾

const { CleanWebpackPlugin } = require("clean-webpack-plugin");
...
plugins: [
new CleanWebpackPlugin()
})
]
 

開發

1 若是某個js發生錯誤,但願可以定位到具體的js中,能夠在webpack.config.js中添加以下選項

devtool: 'inline-source-map'
2  開發工具
  1. webpack's Watch Mode(觀察模式),文件變動動態編譯     在npm的scripts中添加  "watch": "webpack --watch"
  2. webpack-dev-server     爲你提供了一個簡單的 web 服務器,而且可以實時從新加載(live reloading)
  3. webpack-dev-middleware    是一個容器(wrapper),它能夠把 webpack 處理後的文件傳遞給一個服務器(server)

 webpack-dev-server使用

npm install --save-dev webpack-dev-server  

webpack.config.js

 devServer: {
     contentBase: './dist'
  }

package.json 

"start": "webpack-dev-server --open"

執行命令  npm run  start

 

模塊熱替換

該功能容許運行時更新各個模塊,而不是全量刷新.

webpack.config.js

 const path = require('path');
  const HtmlWebpackPlugin = require('html-webpack-plugin');
  const CleanWebpackPlugin = require('clean-webpack-plugin');
+ const webpack = require('webpack');

  module.exports = {
    entry: {
-      app: './src/index.js',
-      print: './src/print.js'
+      app: './src/index.js'
    },
    devtool: 'inline-source-map',
    devServer: {
      contentBase: './dist',
+     hot: true
    },
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Hot Module Replacement'
      }),
+     new webpack.NamedModulesPlugin(),
+     new webpack.HotModuleReplacementPlugin()
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  };
View Code

package.json 

"start": "webpack-dev-server --hotOnly"

 

tree shaking

若是全部代碼都不包含反作用,那麼能夠刪除一些未用到的export導出代碼,

package.json

{ "name": "your-project", "sideEffects": false }

若是有反作用,能夠指定文件{

 "name": "your-project", "sideEffects": [ "./src/some-side-effectful-file.js", "*.css" ] }

生產環境構建


1 建立多個環境配置文件
+|- webpack.common.js

+ |- webpack.dev.js
+ |- webpack.prod.js
2 安裝
npm install --save-dev webpack-merge 用於合併多個配置文件 merge()

3 如開發配置
+ const merge = require('webpack-merge'); + const common = require('./webpack.common.js'); + + module.exports = merge(common, { + devtool: 'inline-source-map', + devServer: { + contentBase: './dist' + } + });
4 npm script 

 

代碼分離

實際上編譯出多個bundle代碼,且公共部分提取到一個文件。避免重複模塊引用到各個bundle中

動態導入

動態import模塊,使得調用的時候編譯出bundle文件。

 

 

 緩存

實際上就是每一次文件bundle文件變動,可以變動文件名,使得客戶端可以感知文件的變化。

只須要在webpack配置output的時候,文件名上添加hash段

output: {
- filename: 'bundle.js', + filename: '[name].[hash].js', path: path.resolve(__dirname, 'dist') }

提取模板manifest
   module.exports = {
       entry: { // 存在多個入口文件
       main: './src/main.js',
   print: './src/print.js',
   vendor: [          // 第三方lib
    'lodash'
   ]    

...
new webpack.HashedModuleIdsPlugin() // 防止標識符moduleId的改變,致使無修改bundle刷新 // 用於生產環境 ], optimization: { splitChunks: { cacheGroups: { commons: { name: "vendor", // 生成共享模塊bundle的名稱 chunks: "initial",//」initial」, 「async」 和 「all」. 分別對應優化時只選擇初始的chunks,所須要的chunks 仍是全部chunks 。 minChunks: 2 //共享模塊的chunks的最小數目 ,默認值是1 } } } }, optimization: { splitChunks: { cacheGroups: { commons: { name: "manifest", chunks: "initial", minChunks: 2 } } } },

  

 

使用環境變量

webpack --env.NODE_ENV=local --env.production --progress

 

在項目中構建路徑值,publicPath 也會在服務器腳本用到,以確保文件資源可以在 http://localhost:8080 下正確訪問

 

相關文章
相關標籤/搜索