1. 程式人生 > >最詳細的webpack說明-------教你手寫webpack4.0

最詳細的webpack說明-------教你手寫webpack4.0

隨著各大技術(vue,webpack,react,微信小程式)生態越來越成熟,這也意味著我們要更加深入的去了解他們,掌握他們。比如你寫vue專案,知道vue-cli。寫的專案也無以倫比,但是你是否又會去了解下vue-cli到底發生了什麼?或許這就是面試官要問你的問題:請手寫一個webpack4.0的配置。

 webpack詳解

webpack是一個打包工具,他的宗旨是一切靜態資源即可打包。

webpack是現代前端技術的基石,常規的開發方式,比如jquery,html,css靜態網頁開發已經落後了。現在是MVVM的時代,資料驅動介面。webpack將現代js開發中的各種新型有用的技術,集合打包。

const path = require('path');            //引入node的path模組
const webpack = require('webpack');            //引入的webpack ,使用lodash
const HtmlWebpackPlugin = require('html-webpack-plugin');        //將html打包
const ExtractTextPl = require('extract-text-webpack-plugin');        //打包的css拆分,將一部分抽離出來
const CopyWebpackPlugin = require('copy-webpack-plugin')
//console.log(path.resolve(__dirname,'dist'));            //實體地址拼接

module.exports = {
    entry: './src/index.js',        //入口檔案 在vue-cli main.js
    output: {                        //webpack 如何輸出
        path: path.resolve(__dirname,'dist'),    //定位,輸出檔案的目標路徑
        filename: '[name].js'
    },
    module: {        //模組的相關配置
        rules: [        //根據檔案的字尾提供一個loader 解析規則
            {
                test: /\.js$/,     //es6 => es5
                include: [
                    path.resolve(__dirname, 'src')
                ],
                //exclude: {},不匹配選項(優先順序高於test和include)
                use: 'babel-loader'
            },
            {
                test: /\.less$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: [
                        'css-loader',
                        'less-loader'
                    ]
                })
            },
            {    //圖片loader
                test: /\.(png|jpg|gif)$/,
                use: [
                    {
                        loader: 'file-loader'     //根據檔案地址載入檔案
                    }
                ]
            }
        ]
    },
    resolve: {    //解析模組的可選項
        //modules: [] //模組的查詢目錄  配置其他的css等檔案
        extension: [".js", ".json", ".jsx", ".less", ".css"] //用到的檔案的副檔名
        alias: {    //模組別名列表
            utils:path.resolve(__dirname,'src/uils')
        }
    },
    plugins: [     //插入的引用,壓縮,分離美化
        new ExtractTextPlugin ('[name].css')    //[name] 預設 也可以自定義name 宣告使用
        new HtmlWebpackPlugin (    //將模板的頭部和尾部新增css和js模板,dist目錄釋出到伺服器上,專案包可以直接上線
            {
                 file: 'index.html',    //打造單頁面應用 最後執行的不是這個
                 template: "./src/index.html"   //vue-cli放在根目錄下
            }
        ),
        new CopyWebpackPlugin ([    //src下其他的檔案直接複製到dist目錄下
            { form:'src/assets/favicon.ico',to:'favicon.ico'}
        ]),
        new webpack.ProvidePlugin(    //引用框架jquery lodash工具庫是很多元件會服用的,省去了import
            {
                '_': 'lodash'
            }

        )
    ],
    devServer: {    //服務於webpack-dev-server  內部封裝了一個express
        port: '8080',
        before(app) {
            app.get('/api/test.json', (req, res) => {
                res.json({
                    code:200,
                    message: 'Hello World'
                })
            })
        }
    }
} 

 搭建流程:

一、前端環境搭建

npm install webpack webpack-cli -g

為什麼webpack會分為兩個檔案呢?在webpack3中,webpack本身和它的cli以前都是在同一個包中,但在第4版中,他們已經將兩者分開來更好地管理它們。

新建一個webpack的資料夾,在其下新建一個try-webpack(防止init時專案名和安裝包同名)並初始化和配置webpack。

npm init -y  //-y 預設所有的配置

二、部署webpack

在上面搭建好的環境專案中,我們來到package.json裡配置我們的scripts。

      "scripts": {
        "build": "webpack --mode production" //我們在這裡配置,就可以使用npm run build 啟動我們的webpack
      },
      "devDependencies": {
        "webpack": "^4.16.0",
        "webpack-cli": "^3.0.8"
      }

 配置好我們webpack的執行環境時,聯想下vue-cli。平時使用vue-cli會自動幫我們配置並生成專案。我們在src下進行專案的開發,最後npm run build 打包生成我們的dist的目錄。不知道你是否還記得,還是讓我們進入下一節讓我們感受下這其中的正個流程吧。

三、npm run build 發生了什麼

在我們的根專案下try-webpack新建一個src目錄。在src目錄下新建一個index.js檔案。在裡面我們可以寫任意的程式碼,以案例為主:

    const a = 1;

寫完之後我們在終端執行我們的命令: npm run build ,你就會發現新增了一個dist目錄,裡面存放著webpack打包好的main.js檔案。這和我們在vue-cli裡操作是一樣的。

四、webpackp配置流程篇

我們在開發是一般會打包src下的什麼檔案呢?我們可以回憶一下,其實vue-cli專案src下不就這幾點嘛:

  1. 釋出時需要的html,css,js

  2. css預編譯器stylus,less,sass

  3. es6的高階語法

  4. 圖片資源.png,.gif,.ico,.jpg

  5. 檔案間的require

  6. 別名@等修飾符

 webpack中webpack.config.js的配置流程線

  • Html在webpack中的配置

在專案的根目錄try-webpack下新建webpack.config.js檔案,以commonJS模組化機制向外輸出,並且新建一個index.html。

    module.exports = {}

配置我們的入口entry,在vue-cli裡相當於跟目錄下的main.js,我們的出口output。我們可以把webpack理解為一個工廠,進入相當於把各種各樣的原料放進我們的工廠了,然後工廠進行一系列的打包操作把打包好的東西,向外輸出,然後就可以去出售了(上線)。

    const path = require('path'); //引入我們的node模組裡的path
    //測試下 console.log(path.resolve(__dirname,'dist')); //實體地址拼接
    module.exports = {
        entry: './src/index.js', //入口檔案  在vue-cli main.js
        output: {       //webpack如何向外輸出
            path: path.resolve(__dirname, 'dist'),//定位,輸出檔案的目標路徑
            filename: '[name].js' //檔名[name].js預設,也可自行配置
        },

 HTML打包我們需要安裝引入html-webpack-plugin

    yarn add html-webpack-plugin -D //在開發環境中安裝
    const HtmlWebpackPlugin = require('html-webpack-plugin')  //引入打包我們的HTML

 在module.exports裡配置我們的plugins(外掛):

     plugins: [  //插進的引用, 壓縮,分離美化
            new HtmlWebpackPlugin({  //將模板的頭部和尾部新增css和js模板,dist 目錄釋出到伺服器上,專案包。可以直接上線
                file: 'index.html', //打造單頁面運用 最後執行的不是這個
                template: 'src/index.html'  //vue-cli放在跟目錄下
            }),
        ],

 配置好後,在終端輸入npm run dev後webpack將我們的html打包好並且自動將我們的js引進來了。

    <body>
        <p class="main">Hello World</p>
    <script type="text/javascript" src="main.js"></script>
    </body>

 live-sever我們的dist目錄,啟動一個8080埠,我們就可以看到我們的Hello World了。這就是我們上線版的頁面。

  •  css在webpack中的配置

 在我們vue-cli裡,我們可以使用css去寫我們的樣式,也可以使用高階stylus,less,sass等預編譯器。這裡就以less為例,看看webpack怎麼將他打包成一個css。

    .main {
      color: red;
    }

 在src目錄下新建我們的style.less檔案,在配置之前我們需要npm我們的css-loader和sass-loader,sass:

 yarn add css-loader less less-loader style-loader-D

 執行完上述命令我們在packge.json裡可以看到我們的配置檔案:

     "devDependencies": {
        "css-loader": "^1.0.0",
        "html-webpack-plugin": "^3.2.0",
        "sass": "^1.9.0",
        "sass-loader": "^7.0.3",
        "webpack": "^4.16.0",
        "webpack-cli": "^3.0.8"
      }

安裝好後,我們開始配置webpack.config.js檔案。這裡申明一下,我們的css在dist目錄下需要和我們的HTML分離,這是還需引入我們的extract-text-webpack-plugin,先然我們安裝下:

yarn add extract-text-webpack-plugin-D

 這裡有一個坑,extract-text-webpack-plugin在4.0並不支援這樣的安裝,大家可自行chrome。於是我們選擇換一種方式,選擇4.00-beta.0版本的:

 yarn add [email protected]

 來到我們的module.exports裡,完成moudel的配置:

      const ExtractTextPlugin = require('extract-text-webpack-plugin')     //打包的css拆分,將一部分抽離出來  
       module: {       //模組的相關配置
            rules: [     //根據檔案的字尾提供一個loader,解析規則
                {
                    test: /\.less$/, //正則匹配我們以.less結尾的檔案
                    use: ExtractTextPlugin.extract({
                        fallback: 'style-loader',
                        use: [
                        'css-loader',
                        'less-loader'
                        ]
                    })
                },
            ]},
         plugins:[
            new ExtractTextPlugin('[name].css'),  //[name] 預設  也可以自定義name  宣告使用
         ]

 我們在執行我們的 npm run build 之後並沒有我們的css,為什麼呢?原來在webpack配置裡css in js。意思是在打包是我們的css是打包在我們的js裡的,所有我們引入了extract-text-webpack-plugin外掛將css從裡面剝離出來。不過又一個問題,require的機制?

 在我們打包過程中,檔案的引用require 按照順序來打包,這就是檔案依賴的機制。

打包好後我們在live-server,發現我們的樣式也上去了,並且css部分分離出來了。

  •  js在webpack中的配置

 現在隨著es6的普及,越來越多的程式碼使用es6了,但是很多瀏覽器並不支援es6,比如async/awiat,const。因此需要我們引用babe來把我們es6的程式碼編譯為es5。在跟目錄下新建.babelrc,簡單配置下:

    {"presets": ["env"]}

 安裝我們的babel並在webpack.config.js裡module/rules下進行配置:

    yarn add babel-loader babel-core  abel-preset-env -D  //babel基本的三個檔案

     {
        test: /\.js$/,  //es6 => es5 
        include: [
            path.resolve(__dirname, 'src')
        ],
        // exclude:[], 不匹配選項(優先順序高於test和include)
        use: 'babel-loader'
    },
  •  圖片資源在webpack中的配置

 在src目錄下新建一個assets檔案,裡面放置幾張圖片。安裝file-loader根據檔案地址載入檔案:

    yarn add file-loader -D

 在webpack.config.js裡module/rules:

     {  
        test: /\.(png|jpg|gif)$/, //匹配所有格式的圖片資源
        use: [
            {
                loader: 'file-loader' 
            }
        ]
    }
  •  別名(@)在webpack中的配置

 在src/index.js裡我們引入:

    const format = require('utils/format')  // utils ?  沒有相對路徑  回想@  => 別名
    在src新建相應的檔案。在format.js裡接受一個引數並把它轉成大寫
    module.exports = function format(chars) {
        return chars.toUpperCase()
    }

 在webpack中如何配置我們的別名呢?在vue-cli中我們經常@一個資料夾,其意思就是在src目錄下,現在我們去一探究竟。在module下,注意跟rules同級。

     resolve: { //解析模組的可選項  
            // modules: [ ]//模組的查詢目錄 配置其他的css等檔案
            extensions: [".js", ".json", ".jsx",".less", ".css"],  //用到檔案的副檔名
            alias: { //模快別名列表
                utils: path.resolve(__dirname,'src/utils')
            }
        },

 其他一些靜態資源在webpack中的配置

  • src下其他的檔案直接複製到dist目錄下,並不是每個檔案都需要打包處理的,很多資源可能直接就可以複製過去。使用我們的 CopyWebpackPlugin外掛

  • 引用框架 jquery lodash工具庫是很多元件會複用的,省去了import。使用webpack.ProvidePlugin外掛

五、npm run dev 發生了什麼

在vue-cli中我們啟動監聽npm run dev可以時時監控我們src下檔案的改動,那他到底發生了什麼呢。在webpack裡其實建立了一個node程序,通過webpack-dev-server其內部封裝了一個node的express模組,其配置項如下:

"scripts": { //在package.json裡宣告下使用指令碼 npm run dev
    "build": "webpack --mode production",
    "start": "webpack-dev-server --mode development"
  }, 
devServer: {  //在webpack.config.js裡配置port
        port: '8080',
        before(app) {
            app.get('/api/test.json', (req, res) => {
                res.json({
                    code: 200,
                    message: 'Hello World'
                })
            })
        }
    } 

此篇教程非本人親自實踐,教程作者github地址:webpack4.0配置的學習demo ( https://github.com/WsmDyj/webpack )

相關推薦

詳細webpack說明-------webpack4.0

隨著各大技術(vue,webpack,react,微信小程式)生態越來越成熟,這也意味著我們要更加深入的去了解他們,掌握他們。比如你寫vue專案,知道vue-cli。寫的專案也無以倫比,但是你是否又會去了解下vue-cli到底發生了什麼?或許這就是面試官要問你的問題:請手寫

手把手一個簡單的 Spring Boot Starter

> 歡迎關注微信公眾號:「Java之言」技術文章持續更新,請持續關注...... > - 第一時間學習最新技術文章 > - 領取最新技術學習資料視訊 > - 最新網際網路資訊和麵試經驗 ## 何為 Starter ? 想必大家都使用過 SpringBoot,在 SpringBoot

都2020年了,聽說還不會歸併排序?手把手歸併排序演算法

本文介紹了歸併排序的基本思想,遞迴方法的一般寫法,最後一步步手寫歸併排序,並對其效能進行了分析。 基本思想 歸併排序是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法的一個非常典型的應用。即先使每個子序列有序,再將已有序的子序列合併,得到完全有序的序列。這裡給出一種遞迴形式的歸併排序實現。 遞迴方

【小松遊開發】【unity實用技能】unity所有特殊文件夾的用途(轉自雨松momo)

unity實用技能這裏列舉出手遊開發中用到了所有特殊文件夾。 Unity3D研究院之手遊開發中所有特殊的文件夾 - 雨松MOMO程序研究院 1.Editor Editor文件夾可以在根目錄下,也可以在子目錄裏,只要名子叫Editor就可以。比如目錄:/xxx/xxx/Editor 和 /Editor 是一

【小松遊開發】【遊戲渲染】單色shader,紋理shader

無單色shader Shader "ChrisShader/OneColorShader" { Properties { _Color ("color", Color) = (0,0,0,0) } SubShader {

【小松遊開發】【unity實用技能】角色頭部跟隨鏡頭旋轉

無這個在端遊上比較場景,在角色展示的時候,當攝像頭在角色身邊上下左右旋轉時,角色頭部跟隨鏡頭旋轉。如天涯明月刀等。 這個在手遊上比較少見,不過實現也沒什麽區別。 首先一般情況下,找到模型的頭部節點,直接用lookAt指向camera就可以了,不過一般需求不會這麽簡單。 比如說,超過頭部扭動極限,頭部需要插值回

【小松遊開發】【unity實用技能】unity性能問題查找方法

無這次先說一下mono內存的性能問題查找方法mono主要是代碼問題,各種解決方案在其他地方會講到,首先就是解決每個尖峰,這個會導致gc,mono堆內存申請等問題。 1.先用cube來測 手機上跑一局看看數據 可以看到在這裏申請了內存,可以看到。這時候首先有個向下的尖峰,這個是執行了一次gc。然後mono發現,

【小松遊開發】【unity系統模塊開發】Unity5.5.2UI打包AssetBundle

無 unity 系統模塊 之前已經有幾篇文章寫打包AssetBundle,但畢竟沒有實際在項目中寫過都寫的比較淺。 剛好最近項目更新Unity5.5.2就順便由我來更新ui打包流程 這裏就把這次的經驗寫一下 這裏還是稍微解釋一下打包的基本目的: 打包ui就是把你做的界面打包出來成assetbund

【小松遊開發】【unity實用技能】給每個GameObject的打開關閉加上一個漸變

無 手遊開發 在遊戲開發中,經常會因為直接將GameObject,setActive的方式打開關閉,這種方式效果太過生硬而給它加上一個Tween 可能是AlphaTween或者ScaleTween。 再加上一個PlayTween來做控制。 這樣子需要在每個GameObject上加上這幾個Compone

【小松遊開發】【unity實用技能】計算目標物體是否在自己的扇形視野範圍

無 51cto 在做遊戲開發中經常會需要到計算扇形的視野或者是受擊範圍的時候。 其實這個分為兩部分, 第一部分是在扇形距離範圍內(也就是不考慮角度,其實是圓形範圍內) 第二部分是扇形角度範圍內 第一部分很簡單,Vector3.Distance(a, b);計算距離 下面講講第二部分,扇形角度範圍內。

【小松遊開發】【unity系統模塊開發】熱更

無 手遊開發 現在的手遊項目如果沒個熱更新叠代根本跟不上, 特別是像我們項目做mmo的更是需要經常改動代碼。 而現在的項目一般會選擇用lua的方式實現熱更新 不過我們項目由於歷史原因沒有使用,用的是另外一種方案 在項目裏的所有GameObject都不掛腳本(NGUI腳本就通過代碼的方式掛上),自己寫的

【小松遊開發】【unity實用技能】線性差值計算實現

無 手遊開發 其實這個unity本身就有的函數Mathf.Lerp(),為什麽還要自己實現呢。 有一個原因就是這個函數返回的是float型,float型如果數字非常大,轉出int時會有精度丟失,也就是轉出來的值不對。 而且非常簡單。 看下公式 public int Lerp(int a,int b,i

【小松遊開發】【unity系統模塊開發】Unity Assetbundle打包筆記

無 手遊開發 *最近項目更新了Unity5.5.2,順便更新了項目的ui打包,也更新一下這邊的筆記 首先打包分為兩部分,一部分是打包成Assetbundle包,一部分是從Assetbundle包解包出來成為可用的資源。 首先說第一部分 打包 所有資源都可以打包,甚至不是資源(一些數據)也可以打包,只要

spring:IOC與DI

前言 依稀記得在2016年剛畢業的時候,在京面試某公司的時候技術總監和我聊到了spring,我比較欣賞一個音樂人Rod Johnson以一人之力造就了spring。當時的個人水平僅僅是知道spring,會簡單使用。當面試官問到我對原始碼的閱讀時,問我大概多久的時間能吃懂spring原始碼,我給了一個答案是1

一個簡單的ORM框架領悟mybatis,hibernate,jpa物件關係對映的祕密

1、ORM介紹     物件關係對映     解決了一個問題: 物件模型和關係模型之間阻抗。     物件模型                     關係模型     物件名稱 Student             表           t_student     物件

攜程系統架構師帶spring mvc,解讀spring核心原始碼!

講師簡介: James老師 系統架構師、專案經理 十餘年Java經驗,曾就職於攜程、人人網等一線網際網路公司,專注於java領域,精通軟體架構設計,對於高併發、高效能服務有深刻的見解, 在服務化基礎架構和微服務技術有大量的建設和設計經驗。   課程內容: 1.為什麼讀Spr

如何出高效整潔的 css 程式碼——css優化

css 寫起來並不難,但在大型專案中,就變得難以管理,特別是不同的人在 css 書寫風格上稍有不同,團隊上就更加難以溝通,為此總結了一些如何實現高效整潔的 css 程式碼原則。css 優化的原則1、不影響頁面的佈局2、去掉不必要的樣式3、合併相同的樣式4、儘可能縮小樣式的大小

黑馬程式設計師如何出優秀的前端工程師簡歷

對於一名想找工作的前端開發工程師而言,簡歷直接關係到面試概率甚至薪資水平,其重要性已不用多說。在HR快速篩選簡歷的情況下,你的簡歷要脫穎而出,就得在短時間內將自己的亮點展示給招聘方。具體怎麼做?黑馬程式設計師前端與移動開發學院的就業指導老師來教你!   第一步:知己知

看過的都哭了!史上詳細!手把手教會完成一個目標識別(目標分割)專案

隨著工業自動化的推進,可能越來越多的同學會感受到老闆接的專案都是傳統工廠自動化程序中的一些環節,比如目標識別。一般有傳統影象方法和順應時代的神經網路方法。其中傳統方法對設計者的影象處理能力要求很高,並且針對每一個專案必須設計特定的識別檢測方法。現在(2018年3月)已經有很多

簡單編寫php驗證類,如何好php程式(含多種驗證規則)

很多人在開發網站的時候往往只是通過簡單的js驗證,當你一不小心在js中多寫了個逗號或者點號,ie6無法識別就直接跳過驗證了。其實最安全的做法還是需要在服務端對使用者輸入的資料做驗證的。本人寫了個簡單的php驗證類,含多種驗證規則,供大家學習參考。原文連結 <?php