webpack入門(3)- 核心內容

webpack入門(2)-安裝,配置,環境,上節傳送門。javascript

Entry(入口)

簡單提一下,Entry是webpack的入口文件,一開始運行webpack它會找到webpack.config.js裏的Entry。它會從這開始着手,構建內部依賴圖。入口點能夠有一個或多個。css

entry的類型

  • string類型
一個入口
entry:'./src/main.js'
複製代碼
  • array類型
配置了多個入口
entry: ['./src/main1.js', './src/main2.js']
複製代碼
  • object類型
對象類型
entry: {
    a: './src/main.js',
    b: ['./src/main1.js', './src/main2.js']
}
複製代碼
  • 多個入口時,每一個入口生成都會生成Chuck。
  • 若是是array類型,則搭配output.library配置項使用時,只有數組裏的最後一個入口文件會被導出。

配置動態Entry(插眼,未理解)

未理解是由於就算設置了函數,好像也沒有動態配置啊? 假如項目裏有多個頁面須要爲每一個頁面的入口配置一個entry,但這些頁面數量可能會不斷增加,這時entry的配置會受到其餘因素的影響致使不能寫成靜態的值。解決辦法就是把entry設置成一個函數去動態返回上面所說的配置:html

//同步函數
entry: () => {
    return {
        a: './pages/a',
        b: './pages/b'
    }
}

//異步函數
entry: () => {
    return new Promise((resolve) => {
        resolve({
            a: './pages/a',
            b: './pages/b'
        })
    })
}
複製代碼

output

Output屬性告訴webpack在哪裏輸出它所建立的bundles,也可指定bundles的名稱,默認位置爲./dist。整個應用結構都會被編譯到指定的輸出文件夾中去,你能夠經過在配置中指定一個 output 字段,來配置這些處理過程。最基本的屬性包括filename(文件名)和path(輸出路徑)。前端

Chuck的名稱

向上面的main.js中,main就是Chuck名稱。Chunk的名稱和Entry的配置有關。vue

  • 若是entry是string類型或者是array類型,只會生成一個Chuck。
  • 若是entry是一個object,就可能出現多個chunk,這時候的chunk值是object名稱。好比上面的a.js,b.js。Chuck名稱在output能夠配置。

多個入口時怎麼配置filename

當經過多個入口起點(entry point)、代碼拆分(code splitting)或各類插件(plugin)建立多個 bundle的時候,能夠有如下幾種賦bundle名稱的方式。[佔位符]能夠理解爲小程序的{{ }}html5

  • 使用入口名稱賦值,[name]爲entry的key值,好比a.bundle.js,b.bundle.js
filename: "[name].bundle.js"
複製代碼
  • 使用內部 chunk id,從0開始
filename: "[id].bundle.js"
複製代碼
  • 使用每次構建過程當中,都會生成一段Hash值
filename: "[name].[hash].bundle.js"
複製代碼
  • 使用基於每一個 chunk 內容的 hash值,能夠理解爲版本號(Git裏面的)或者md5值。文件內容發生改變,chunkhash就會改變。在這裏能夠用到:項目上線,只上線那些被改過的文件
filename: "[chunkhash].bundle.js"
複製代碼
取5位Hash值,默認爲20位。
filename: "[chunkhash:5].bundle.js"
複製代碼

path

output.path 配置輸出文件存放在本地的目錄,必須是 string 類型的絕對路徑。一般經過 Node.js 的 path 模塊去獲取絕對路徑:java

path: path.resolve(__dirname, 'dist_[hash]')
複製代碼

__dirname就是當前文件所在的文件夾的名字。webpack

publicPath

對構建出的資源進行異步加載(圖片,文件)。加載這些異步資源須要對應的 URL 地址。默認值是空字符串「 」。簡單說,就是靜態文件託管在cdn上。
若是你這麼配置:git

output:{
    filename:'[name]_[chunkhash:8].js',
    publicPath:'https://www.qdtalk.com/assets/'
}
複製代碼

打包編譯以後,HTML頁面就變成了這個:es6

<script src="https://www.qdtalk.com/assets/a_12345678.js"></script>
複製代碼

上面只是舉了output的幾個經常使用參數。

Loader

Loader在webpack中承擔翻譯的工做。 由於webpack自身只支持加載jsjson文件,把源文件轉化翻譯後輸出新結果,且一個文件還能夠鏈式的通過多個翻譯員翻譯

以處理SCSS文件爲例:

  • SCSS 源代碼會先交給 sass-loaderSCSS 轉換成 CSS
  • sass-loader 輸出的 CSS 交給 css-loader 處理,找出 CSS 中依賴的資源、壓縮 CSS 等;
  • css-loader 輸出的 CSS 交給 style-loader 處理,轉換成經過腳本加載的 JavaScript 代碼。

經常使用的Loader

  • 樣式:style-loader、css-loader、less-loader、sass-loader等。
  • 文件:raw-loader、file-loader 、url-loader
  • 編譯:babel-loader、coffee-loader 、ts-loader
  • 校驗測試:mocha-loader、jshint-loader 、eslint-loader
  • vue-loader、coffee-loader、babel-loader等能夠將特定文件格式轉成js模塊、將其餘語言轉化爲js語言和編譯下一代js語言
  • file-loader、url-loader等能夠處理資源,file-loader能夠複製和放置資源位置,並能夠指定文件名模板,用hash命名更好利用緩存。
  • url-loader能夠將小於配置limit大小的文件轉換成內斂Data Url的方式,減小請求。
  • raw-loader能夠將文件已字符串的形式返回
  • imports-loader、exports-loader等能夠向模塊注入變量或者提供導出模塊功能
  • expose-loader:暴露對象爲全局變量

安裝Loader

以安裝css-loader和style.loader爲例,直接在終端:

npm install css-loader style-loader --save-dev
複製代碼

配置單個Loader

webpack.config.js

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: 'css-loader'
            }
        ]
    }
}
複製代碼
  • test:後面接一個正則表達式,表示有那些後綴文件被處理。
  • use:表示應該用什麼loader。

配置多個loader

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

其餘配置方法

  • 直接在命令行
webpack --module-bind 'txt=raw-loader'
複製代碼
  • 內聯
import txt from 'raw-loader!./file.txt'
複製代碼

但這兩種方法都不推薦。仍是在webpack.config.js配參數更好。

幾個重要的loader

Babel

Babel 可讓你使用ES2015/16/17 寫代碼而不用顧忌瀏覽器的問題,Babel 能夠幫你轉換代碼。

  • 安裝幾個必要的Babel庫,
npm i --save-dev babel-loader babel-core babel-preset-env
複製代碼
babel-loader讓webpack去處理一些使用了es6的js文件。
 babel-core 提供一系列API,實際上是讓babel-loader去調用babel-core的API。
 babel-preset-env 這個庫能夠根據環境的不一樣轉換代碼
複製代碼
  • 配置babel規則。在package.json裏面增長一個babel屬性。做用是設置項目中的babel轉碼規則和使用到的babel插件,格式以下:
"babel":{
  "presets": ["evn"],//設定轉碼規則
  "plugins": []//要用到的插件
}
複製代碼

表示告訴npm,在本項目中將使用babel,而且使用babel-preset-env規則進行轉碼。

  • 除了上一種寫法外,還有另一種方法(推薦寫法)。在根目錄下面新建.babelrc文件,而後作一下配置:
{
  "presets": ["babel-preset-env"]
}

複製代碼
  • 上面已經配置好babel的規則,可是webpack依然不知道什麼時候使用該規則。咱們還要再接着在配置裏寫入
use: 'babel-loader'
複製代碼

但要注意的是,只有js文件纔可使用babel

處理圖片

  • npm i --save-dev url-loader file-loader
  • webpack.config.js裏面修改配置:
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use : [
  {
     loader: 'url-loader',
     options: {
      // 限制 圖片大小 10000B,小於限制會將圖片轉換爲 base64格式
         limit: 10000,
      // 超出限制,建立的文件格式
      // build/images/[圖片名].[hash].[圖片格式]
         name: 'images/[name].[hash].[ext]'
    }
  }
]
複製代碼

Plugins(插件)

插件用來拓展webpack功能,能夠用於執行範圍更廣的任務,包括打包、優化、壓縮、搭建服務器等等,功能十分強大。要是用一個插件,通常是先使用npm包管理器進行安裝,而後在配置文件webpack.config.js中require引入,最後在這個文件下使用new來建立一個實例。 Loader一次只能處理單個相同類型的文件,可是plugins能夠對整個過程起做用。

經常使用的plugin插件

  • webpack內置UglifyJsPlugin插件,壓縮和混淆代碼。
  • webpack內置CommonsChunkPlugin,提升打包效率,將第三方庫和業務代碼分開打包
  • ProvidePlugin:自動加載模塊,代替requireimport
  • html-webpack-plugin能夠根據模板自動生成html代碼,並自動引用css和js文件
  • extract-text-webpack-plugin 將js文件中引用的樣式單獨抽離成css文件
  • DefinePlugin 編譯時配置全局變量,這對開發模式和發佈模式的構建容許不一樣的行爲很是有用。
  • HotModuleReplacementPlugin熱更新
  • optimize-css-assets-webpack-plugin 不一樣組件中重複的css能夠快速去重
  • webpack-bundle-analyzer 一個webpack的bundle文件分析工具,將bundle文件以可交互縮放的treemap的形式展現
  • compression-webpack-plugin 生產環境可採用gzip壓縮JS和CSS
  • happypack:經過多進程模型,來加速代碼構建

一個簡單的插件使用

  • npm install --save-dev html-webpack-plugin安裝一個插件。有的插件webpack自帶,若是沒有,則需用npm安裝。
  • const HtmlWebpackPlugin = require('html-webpack-plugin');在webpack.config.js中引入。
  • new一個實例
plugins: [
 
  new HtmlWebpackPlugin({
  template: './src/index.html', //以src目錄下的index.html文件爲模板生成html5新文件
  filename: 'index.html',//指定生成的HTML文件叫啥名
  inject: 'head',//指定把腳本script標籤放在那裏,這裏放在<head>標籤裏。還能夠放<body>
  })
]
複製代碼

利用html-webpack-plugin插件自動生成html文件

爲何要自動生成HTML

每次執行webpack打包生成js文件後,都必須在index.html中手動插入打包好的文件的路徑。但在真實生產環境中,一次運行webpack後,完整的index.html應該是被自動生成的。 例如靜態資源、js 腳本都被自動插入了。

根目錄下的index.html文件

根目錄下的index.html會被html-webpack-plugin做爲最終生成的 html 文件的模板。打包後,相關引用關係和文件路徑都會按照正確的配置被添加進去。

配置

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
 entry: {
    app: "./src/app.js"
  },
  output: {
    publicPath: __dirname + "/dist/",
    path: path.resolve(__dirname, "dist"),
  },
    plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "./index.html",
      chunks: ["app"], // entry中的app入口才會被打包
      minify: {
        // 壓縮選項
        collapseWhitespace: true
      }
    })
  ]
}
複製代碼

最後執行打包命令,而後在dist目錄下就給你自動生成了index.html文件。dist目錄下的index.html文件是以根目錄下的inde.html文件爲模板的。

其餘幾個核心概念

Module(模塊)

對於webpack,模塊不只僅是javascript模塊,它包括了任何類型的源文件,不論是圖片、字體、json文件都是一個個模塊。Webpack支持如下的方式引用模塊:

  • ES2015 import 方法
  • CommonJs require() 方法
  • AMD define 和 require 語法
  • css/sass/less文件中的 @import 語法
  • url(...)和 的圖片路徑

Dependency Graph(依賴關係圖)

所謂的依賴關係圖是webpack根據每一個模塊之間的依賴關係遞歸生成的一張內部邏輯圖,有了這張依賴關係圖,webpack就能按圖索驥把全部須要模塊打包成一個bundle文件了。

Mode(模式)

分爲開發模式development和生產模式production 。兩種模式的區別在於一個是爲生產環境編譯打包,一個是爲了開發環境編譯打包。生產環境模式下,webpack會自動對代碼進行壓縮等優化,省去了配置的麻煩。

結語

webpack斷斷續續終於算是入門了。與其餘技能點相比,webpack算是比較酸澀難懂。可是學無止境,我學webpack的還有很長的路要走。

歡迎訪問個人博客,會分享一些技術文章,一塊兒學習前端。

相關文章
相關標籤/搜索