webpack配置工程師(一):基本篇

簡介

爲本身瞭解webpack的過程作一個總結,也但願對想要了解的小夥伴有所幫助。javascript

準備工做

既然是學習瞭解webpack,那我假定你瞭解npm和node.js了css

核心概念

先對核心概念有個大概的瞭解,不理解也不要緊,看完後面的例子應該會有必定的認識。html

  • Entry:入口,Webpack 執行構建的第一步將從 Entry 開始,可抽象成輸入。
  • Module:模塊,在 Webpack 裏一切皆模塊,一個模塊對應着一個文件。Webpack 會從配置的 Entry 開- 始遞歸找出全部依賴的模塊。
  • Chunk:代碼塊,一個 Chunk 由多個模塊組合而成,用於代碼合併與分割。
  • Loader:模塊轉換器,用於把模塊原內容按照需求轉換成新內容。
  • Plugin:擴展插件,在 Webpack 構建流程中的特定時機注入擴展邏輯來改變構建結果或作你想要的事情。
  • Output:輸出結果,在 Webpack 通過一系列處理並得出最終想要的代碼後輸出結果。

環境準備

1.新建一個工程目錄study_webpack(用於嘗試各類例子)
2.全局安裝webpack(爲了方便用命令,安裝的版本看下面的文件)vue

cnpm install -g webpack
cnpm install -g webpack-cli

tip:考慮到後續的一些插件的版本問題,放出個人package.jsonjava

{
  "name": "webpack-study-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {},
  "keywords": [],
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "css-loader": "^1.0.1",
    "html-webpack-plugin": "^3.2.0",
    "vue-loader": "^15.4.2",
    "vue-template-compiler": "^2.5.17",
    "webpack": "^4.25.1",
    "webpack-cli": "^3.1.2"
  },
  "dependencies": {
    "vue": "^2.5.17"
  }
}

demo01(one entry)

基本栗子演示單個入口webpack打包結果,後續例子無特殊說明均採用該目錄結構node

clipboard.png

在demo1目錄下準備調用文件dist/index.htmlwebpack

<!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>
</head>

<body>
    <!-- 引入打包的文件 -->
    <script src="./bundle.js"></script>
</body>

</html>

入口文件index.jsweb

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

webpack配置webpack.config.jsshell

const path=require('path');

module.exports = {
    entry: "./index.js",
    output: {
        filename: "bundle.js",
        path:path.resolve(__dirname,"./")
    }
};

在終端中執行webpack命令(webpack.config.js所在的目錄)npm

tip:webpack默認讀取目錄下的webpack.config.js的配置文件。

執行結果

Hash: 7a488a408fbb07bfacd8
Version: webpack 4.25.1
Time: 273ms
Built at: 2018-11-11 16:19:40
    Asset       Size  Chunks             Chunk Names
bundle.js  968 bytes       0  [emitted]  main
Entrypoint main = bundle.js
[0] ./index.js 40 bytes {0} [built]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

第一個webpack的例子成功了,是否是很簡單,立刻就能夠成爲webpack配置工程師了,想一想還有些小激動。

demo02(multiple entry)

每每一個應用不單單隻有一個入口(第三方庫啦,多個頁面啦,等等)

在demo2目錄下面寫調用文件dist/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>
</head>
<body>
    <script src="./bundle1.js"></script>
    <script src="./bundle2.js"></script>
</body>
</html>

而後是入口文件module1.jsmodule2.js

document.write("<h1>Hello Module1</h1>");
document.write("<h1>Hello Module2</h1>");

打包結果執行結果

clipboard.png

demo03(use loader)

Webpack 把一切文件看做模塊,要支持非 JavaScript 類型的文件,須要使用 Webpack 的 Loader機制

target:編譯.vue文件

準備工做:

cnpm i vue --save
cnpm i vue-loader --save-dev
cnpm i css-loader --save-dev
cnpm i vue-template-compiler --save-dev

新建demo03目錄,調用文件dist/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>
</head>
<body>
    <div id="app"></div>
    <script src="./bundle.js"></script>
</body>
</html>

入口文件index.js

import Vue from "vue";
import App from "./index.vue";

/* eslint-disable no-new */
new Vue({
    el: "#app",
    template: "<App/>",
    components: { App }
});

index.vue文件

<template>
  <div id="app">
      {{msg}}
  </div>
</template>

<script>
export default {
    name: "app",
    data: function() {
        return {
            msg:"hello loader"
        };
    }
};
</script>

<style>
</style>

最後是配置文件webpack.config.js

const VueLoaderPlugin = require("vue-loader/lib/plugin");

module.exports={
    entry:"./index.js",
    output:{
        filename:"bundle.js"
    },
    resolve: {
        alias: {
            vue$: "vue/dist/vue.js" // 設置別名,找到node_modules下的vue
        },
        extensions: [".js", ".json",".vue"] // 支持.vue擴展
    },
    module:{
        rules:[
            {
                test:/\.vue$/,
                loader:"vue-loader" // 添加vue-loader
            }
        ]
    },
    plugins:[
        new VueLoaderPlugin() // vue-loader須要添加插件配置
    ]
}

clipboard.png

相比前面的例子拋開其中的優化配置(別名之類的),實際上添加了一個module.rules選項,這個選項的做用專門用來配置loader,其中test字段經過正則匹配模塊擴展名,告訴webpack對非javascript模塊應用什麼loader。

多個loader的例子容我省略,你(我)辣(偷)麼(個)機(懶)智

demo04(use plugins)

Plugin 是用來擴展 Webpack 功能的,經過在構建流程裏注入鉤子實現,它給 Webpack 帶來了很大的靈活性

因此,綜上所述,plugins就是用來擴展webpack的,好比工做流(代碼壓縮),提升開發效率(熱重載,靜態服務器)等。

ps:其實上一個例子有plugins配置,不過那是vue-loader須要

target:動態生成html

前面的例子,咱們的調用的html都是預先生成的,實際開發中幾十個頁面打包一次純手動成本過高,咱們以html-webpack-plugin插件爲例

入口文件index.js

var name1="hello";
var name2="plugins";

document.write(`<h1>${name1} ${name2}</h1>`);

配置文件webpack.config.js

先安裝插件

cnpm i html-webpack-plugin --save-dev
var HtmlWebpackPlugin = require("html-webpack-plugin");
var path = require("path");

module.exports = {
    entry: "./index.js",
    output: {
        path: path.resolve(__dirname, "./dist"),
        filename: "bundle.js"
    },
    plugins: [new HtmlWebpackPlugin({ // 在插件數組裏面加一個插件就行了,是否是so easy
        title:"demo04 title",
        template:"./template.html",
        inject:true
    })]
};

tip:該插件咱們配置一個html模板

模板文件template.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><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
    
</body>
</html>

clipboard.png

想一想幾十個頁面經過一個模板生成是否是效率會高上很多呢

未完待續,沒寫多少頁面卡的不行

clipboard.png

相關文章
相關標籤/搜索