從零開始學webpack:基礎配置

webpack是什麼

webpack是一個很是實用的靜態模塊打包工具,它經過遞歸的方式構建一個包含應用程序須要的全部模塊的依賴圖,而後將這些文件打包成一個或多個bundle輸出javascript

爲何要使用webpack

早期的開發中都是將各類靜態文件(好比圖片,CSS等)手動引入到html中,而後直接在瀏覽器中運行html文件;在這個時期,遇到大型項目時要麼將全部的JS所有寫在一個文件中,要麼是引入多個腳本;前一種方式會致使代碼混亂;後一種方式會致使HTTP請求過多;css

隨着前端技術的發展,開始使用模塊化對代碼進行分割,讓代碼可以複用且更方便維護,但瀏覽器對模塊化的支持並不統一;html

webpack最核心的功能就是解決模塊之間的依賴問題,經過對webpack的簡單配置便可完成代碼轉換,壓縮,文件優化,模塊加載及打包等功能前端

安裝webpack

npm install webpack webpack-cli -D
複製代碼

核心概念

entry: 構建入口

entry用於告訴webpack應該使用哪一個模塊作爲構建的開始;其默認值爲./src/index.jsjava

module.exports = {
    entry: './src/main.js'
}
複製代碼

output: 構建輸出

output指定了webpack構建完成後的文件輸出位置以及輸出後的文件名等信息;node

const path = require('path') // nodeJs內置的path模塊
module.exports = {
    entry: './src/main.js',
    output: {
        filename: 'main.[hash].js', // 輸出文件的文件名
        path: path.resolve(__dirname, 'dist')
        // path屬性用於指定輸出的文件路徑,它必須接收絕對路徑
        // path.resolve()方法用於將相對路徑轉換成絕對路徑
    }
}
複製代碼

[hash]: [hash]用於解決靜態文件緩存問題;靜態文件內容更改而文件名不更改的狀況下,可能會由於瀏覽器緩存問題而獲取不到新的內容,經過hash可讓每一次打包的文件名不重複jquery

mode: 配置模式

webpack會根據配置模式自動調用相應的內置優化項; 可選的配置模式有development, production, none, 默認值爲productionwebpack

配置模式能夠在webpack的配置文件中顯式的指定git

module.exports = {
    mode: 'development'
}
複製代碼

在實際的項目開發中,更多的是經過腳本的方式執行CLI,經過CLI的參數傳遞github

<!-- package.json -->
"scripts": {
    "build": "webpack --mode=production",
    "dev": "webpack-dev-server --mode=development"
}
複製代碼

loader: 模塊代碼轉換器

loader用於對模塊中的源代碼進行轉換,webpack本質上只能理解JavaScript和JSON文件,若是要解析其餘代碼就須要對代碼進行轉換,好比將typeScript代碼轉換成javascript代碼;

經常使用的loader屬性

  • test: 使用正則篩選出須要使用loader的文件
  • use: 轉換時須要使用的loader,能夠同時使用多個loader;經過對象的方式能夠對loader進行個性化的配置
  • include: 指定loader必需要應用的文件夾
  • exclude: 指定loader須要排除不處理的文件夾

loader的執行順序

loader的執行順序是從下往上,從右往左;也就是說,在代碼中越靠後的loader越先執行;在下面的例子中,css-loader比style-loader先執行

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', ''css-loader]
            }
        ]
    }
}
複製代碼

plugin

webpack的插件系統,經過插件能夠擴展webpack的功能

基礎配置

webpack解析時默認從webpack.config.js文件提取配置,因此將webpack的相關配置都寫到這個文件中

<!-- webpack.config.js -->
const path = require('path')
module.exports = {
    entry: './main.js',
    output: {
        filename: 'index.js',
        path: path.resolve(_dirname, 'dist')
    }
}
複製代碼

以上就是一個最基礎的webpack配置,以當前(webpack.config.js所在的目錄)目錄下的main.js爲入口開始構建,輸出到當前目錄下的dist文件夾中;

配置HTML模板

在單頁面應用開發中都須要使用一個html文件做爲模板;html-webpack-plugin用於指定一個html文件做爲模板,並以這個模板爲基礎引入打包後的js,css等文件,而後根據output的配置輸出

安裝

npm install html-webpack-plugin -D
複製代碼

配置

<!-- webpack.config.js -->
let HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    // 省略其餘代碼
    plugins: [
        template: './index.html',   // 指定模板文件路徑
        filename: 'index.html',   // 指定打包後輸出的模板文件名
        minify: {   // 指定模板壓縮的規則
            removeAttributeQuotes: true,     // 刪除屬性的雙引號
            collapseWhitespace: true,   // 摺疊空行
        },
        hash: true, // 添加hash戳,hash能夠避免緩存問題
    ]
}
複製代碼

在上面的配置中,指定了模板的路徑(template)以及打包完成後輸出的文件名稱(filename), 同時指定了模板文件的壓縮規則(minify), 爲解決緩存問題添加了hash戳,輸出的模板文件都會帶上hash值;更多html-webpack-plugin的配置能夠參考官方文檔

本地開發服務配置

webpack-dev-server提供了一個本地的web開發服務和熱更新的能力;經過這個本地server直接訪問應用能夠更好的開發和調試

安裝

npm install webpack-dev-server -D
複製代碼

配置

module.exports = {
    devServer: {
        port: '8080',   // 開發服務端口
        host: 'localhost',
        progress: true, // 配置打包進度條
        contentBase: './dist',   // 指定靜態服務的啓動文件夾
    }
}
複製代碼

package.json文件中配置一個腳本,

<!-- package.json -->
"scripts": {
    "dev": "webpack-dev-server --mode=development"
}
複製代碼

此時經過npm run dev就能夠啓動一個本地開發服務了;更多關於webpack-dev-server的配置能夠參考官方文檔

webpack中css的配置

普通css的配置

webpack中css的解析主要依賴兩個loader來完成:css-loaderstyle-loader

css-loader主要負責解析@import和url()
style-loader的主要做用是將css經過style標籤的方式添加到模板文件中

安裝

npm install style-loader css-loader -D
複製代碼

配置

<!-- webpack.config.js -->
module.exports = {
    // 省略其餘代碼
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            }
        ]
    }
}
複製代碼

由於須要先解析css中的@import和url()語法,因此css-loader應該寫style-loader以後

less和sass的配置

less和sass的解析依賴於less-loadersass-loader

使用這兩個loader以前須要安裝less和sass模塊

安裝

npm install less less-loader node-sass sass-loader -D
複製代碼

配置

<!-- webpack.config.js -->
module.exports = {
    // 省略其餘代碼
    module: {
        rules: [
            {
                test: /\.less/,
                use: ['style-loader', 'css-loader', 'less-loader']
            },
            {
                test: /\.scss/,
                use: [
                    'style-loader',
                    'css-loader',
                    {
                        loader: 'sass-loader',
                        options: {}
                    }
                ]
            }
        ]
    }
}
複製代碼

個性化loader配置: 在上面的配置中,scss-loader使用了對象語法進行配置,這種方式能夠經過options對象來對loader進行更多個性化的配置

添加瀏覽器前綴

因爲瀏覽器對css新屬性的兼容性不統一,因此一些新的css屬性在使用的時候須要爲不一樣的瀏覽器加上前綴

autoprefixer經過postcss配置後能夠爲自動爲css添加不一樣瀏覽器的前綴

安裝

npm install autoprefixer postcss-loader -D
複製代碼

配置

<!-- webpack.config.js -->
module.exports = {
    // 省略其餘代碼
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader','postcss-loader' 'css-loader']
            }
        ]
    }
}
複製代碼

接下來還須要經過postCSS配置autoprefixer才能自動添加前綴

<!-- postcss.config.js -->
const autoprefixer = require('autoprefixer')
module.exports = {
    plugins: [autoprefixer]
}
複製代碼

提取css到單獨文件中

經過前面的配置,已經能夠解析css而且將css經過style標籤的形式插入到模板中; 可是若是css內容過多,則會讓模板文件中的css顯得臃腫,這個時候就須要將css單獨抽離出一個文件,以link的方式引入模板

mini-css-extract-plugin插件用於將CSS提取到單獨的文件中

安裝

npm install mini-css-extract-plugin -D
複製代碼

配置

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
    // 省略其餘代碼
     plugin: [
        new MiniCssExtractPlugin({
            filename: 'css/index.css'
        })
    ]
}
複製代碼

filename: 抽離以後的css文件名稱,若是使用路徑的方式則會將文件抽離到指定的路徑下,以上面的代碼爲例,index.css會抽離到./dist/css/index.css

使用mini-css-extract-plugin插件以後,css將會抽離成單獨的文件,因此須要使用MiniCssExtractPlugin.loader替換原有的style-loader

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
    // 省略其餘代碼
     plugin: [
        new MiniCssExtractPlugin({
            filename: 'index.css'  // 抽離後的css文件名
        })
    ],
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            }
        ]
    }
}
複製代碼

webpack中JS的配置

因爲瀏覽器對新的ES語法支持並非一致,爲了保證代碼的兼容性,須要將新的ES語法(ES6,ES7,ES8等)轉換爲瀏覽器都支持ES5語法;在webpack中,這個轉換的功能主要經過babel來完成

安裝

npm install babel-loader @babel/core @babel/preset-env -D
複製代碼

配置

module.exports = {
    // 省略其餘代碼
    rules: [
        {
            test: '/\.js$/', 
            use: {
                loader: 'babel-loader',
                options: {
                    presets: [
                        '@babel/preset-env'
                    ]
                }
            },
            include: path.resolve(__dirname, 'src'),  // 但願應用的文件夾
            exclude: /node_modules/ // 須要排除的文件夾
        }}
    ]
}
複製代碼

文件壓縮

webpack中的文件壓縮經過配置optimization來完成

module.exports = {
    // 省略其餘代碼
    optimization: [
    
    ]
}
複製代碼

css文件壓縮

optimize-css-assets-webpack-plugin插件能夠用於css文件的壓縮

安裝

npm install optimize-css-assets-webpack-plugin -D
複製代碼

配置

const OptimizeCss = require('optimize-css-assets-webpack-plugin')
module.exports = {
    // 省略其餘代碼
    optimization: [
        new OptimizeCss()
    ]
}
複製代碼

js文件壓縮

uglifyjs-webpack-plugin插件用於JS文件的壓縮

安裝

npm install uglifyjs-webpack-plugin -D
複製代碼

配置

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
    // 省略其餘代碼
    optimization: [
        new UglifyJsPlugin({
            parallel: true
        })
    ]
}
複製代碼

圖片的配置

webpack中的圖片配置可使用url-loader來完成,url-loader與file-loader功能類似;可是它能夠在圖片大小低於指定的限制時,將圖片轉換爲base64格式,以此減小HTTP請求

安裝

npm install url-loader -D
複製代碼

配置

module.exports = {
    // 省略其餘代碼
    module: {
        rules: [
            {
                test: /\.(png|jpg|gif)$/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 10240,   // 單位爲字節
                            outputPath: 'img/'
                        }
                    }
                ]
            }
        ]
    }
}
複製代碼

outputPath: 指定圖片輸出路徑,已上面的配置爲例,圖片文件將輸出到./dist/img/目錄下

全局變量的配置(以jquery爲例)

當下前端開發的主流框架都是以數據驅動的,不多去操做DOM;可是若是項目業務特殊須要用到jQuery的話,爲了不每一次使用的時候都經過import去引入,可使用webpack配置一個全局變量

webpack全局變量的配置主要使用webpack的內置模塊(內置模塊不須要經過npm安裝,直接使用便可)ProvidePlugin來完成,詳細內容能夠參考官方文檔

配置

npm install jquery
module.exports = {
    // 省略其餘代碼
    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery"
        })
    ]
}
複製代碼

打包清空輸出目錄

爲了不屢次打包後輸出目錄混亂(舉例:每次打包都輸出一個名稱帶hash的文件,屢次打包後就會產生多個文件在同一個目錄中,可是隻有最後一次輸出的文件纔有用)的問題,能夠經過clean-webpack-plugin插件,在每一次打包的時候都將輸出目錄清空,這樣,每一次打包後的輸出文件夾中都會比較乾淨

安裝

npm install clean-webpack-plugin -D
複製代碼

配置

const CleanWebpackPlugin = require('clean-webpack-plugin')
module.exports = {
    // 省略其餘代碼
    plugins: [
        new CleanWebpackPlugin()
    ]
}
複製代碼

寫在最後

本文主要了解了webpack中的一些核心概念並介紹了一些經常使用配置所須要的插件,loader等,經過這些配置就已經能夠知足多數場景的基本開發需求了

本文所對應的配置源碼已提交到個人github

end

相關文章
相關標籤/搜索