前端構建_webpack

104828720發表於2019-02-16

webpack 是什麼?

webpack是一個前端模組化打包工具指(由於模組化開發,所以需要打包,這裡所說的模組化開發主要指JS)

由於現代前端應用程式越來越複雜,需要採用模組化進行開發,但瀏覽器還未支援模組化開發,所以webpack才誕生

webpack預設只支援js的模組化(CommonJS/ES6/AMD),如果需要把其他檔案(css/圖片等)也當成模組引入,就需要相對應的loader解析器

現代前端與傳統前端的區別

安裝

  • webpack

使用NPM進行安裝,有2種方式:全域性安裝、區域性安裝(區域性又分為生產區域性安裝和開發區域性安裝

全域性安裝: npm i -g webpack

區域性開發安裝: npm i -D webpack  // (推薦此)JS應用在生產環境上不需要webpacke,所以無需使用生產區域性安裝

區域性安裝的專案,會在當前專案中node_module中,不會汙染全域性

  • webpack-cli
v4.0.0之後,除了要安裝webpack,還需要安裝webpack-cli

區域性開發安裝: npm i -D webpack-cli

配置

  • 預設配置
在應用根目錄下,定義webpack.config.js檔案

執行webpack時,直接在命令列輸入webpack (會預設尋找webpack.config.js配置檔案)
  • 自定義配置
在應用根目錄下,自定義webpack.config.dev.js檔案

執行webpack時,直接在命令列輸入webpack --config webpack.config.dev.js

如果把webpack.config.dev.js配置檔案放在根目錄下的資料夾裡呢?
  • 最簡單配置 —— 打包JS模組
const path = require(`path`);

module.exports = {
    entry: `./src/index.js`,
    output: {
        path: path.resolve(__dirname, `dist`),
        filename: `bundle.js`
    },
    mode: `development`
};

外掛

  • 簡單建立 HTML 檔案,用於伺服器訪問

所有打包好的JS檔案,都要有一個html檔案來引入,否則瀏覽器無法瀏覽,這個功能就是webpack外掛HtmlWebpackPlugin功能

1、安裝
npm install --save-dev html-webpack-plugin

2、在webpack.config.js檔案中配置
const path = require(`path`);
const HtmlWebpackPlugin = require(`html-webpack-plugin`);

module.exports = {
    entry: `./src/index.js`,
    output: {
        path: path.resolve(__dirname, `dist`),
        filename: `bundle.js`
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: `main.html`
        })
    ],
    mode: `development`
};

伺服器 for dev

webpack提供了一個用於開發使用的伺服器:webpack-dev-server,前端應用開發,需要一個除錯開發伺服器來看即時效果

  • 安裝
npm install webpack-dev-server --save-dev
  • 配置
1、配置執行伺服器命令
在package.json中,配置
"scripts": {
    "sdev": "webpack-dev-server"
}
*****注意:預設伺服器是讀取webpack.config.js檔案,如果自定義了,需要加上--config webpack.config.dev.js*****

2、在webpack配置檔案中配置
module.exports = {
    entry: `./src/index.js`,
    output: {
        path: path.resolve(__dirname, `dist`),
        filename: `bundle.js`
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: `main.html`
        })
    ],
    mode: `development`,
    devServer: {
        open: true,  // 自動開啟
        contentBase: path.join(__dirname, `dist`),
        index: `main.html`
    }
};
  • 執行原理
執行webpack,根據配置檔案,會生成打包後的檔案(硬碟)
執行webpack-dev-server,根據配置檔案,會生成打包後的檔案(記憶體),並啟動伺服器

Babel 語法轉換

Babel 是一個 NodeJS的獨立應用,用於把ES2015/ES2016/ES2017/React轉換成ES5

用法:
1、在瀏覽器中使用
2、webpack打包中使用 (以下主要講解這種方式)
3、命令列直接使用

  • 安裝
npm install -D babel-loader @babel/core @babel/preset-env 

CSS 引入

在webpack中任何一個東西都稱為模組,js就不用說了。一個css檔案,一張圖片、一個less檔案都是一個模組,都能用匯入模組的語法(commonjs的require,ES6的import)匯入進來。webpack自身只能讀懂js型別的檔案,其它的都不認識。但是webpack卻能編譯打包其它型別的檔案,像ES6、JSX、less、typeScript等,甚至css、images也是Ok的,而想要編譯打包這些檔案就需要藉助loader

import(匯入)是ES6 Module的模組化語法,與export(匯出)是一對對應的技術,所以 *ES6 所說的匯入都是匯入 JS 檔案*,而這個JS檔案一般會有匯出語法

  • 問題:為何webpack中能使用ES6 import語法匯入CSS檔案?
其實ES6 import語法沒有規定一定要匯入JS檔案,但如果你匯入的是非JS檔案,執行時會報錯的

webpack借用了ES6的匯入/匯出語法,本身就支援匯入JS檔案
如果需要轉ES5,需要額外配置一個loader

不同的是:
webpack還支援匯入別的檔案(圖片、css、less等),語法也是借用了ES6的匯入/匯出語法,需要額外配置一個loader
  • 安裝
npm i style-loader css-loader -D
  • 配置
const path = require(`path`);
const HtmlWebpackPlugin = require(`html-webpack-plugin`);

module.exports = {
    mode: `development`,
    entry: `./src/index.js`,
    output: {
        path: path.resolve(__dirname, `dist`),
        filename: `bundle.js`
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: `index.html`,
            template: `./public/index.html`
        })
    ],
    devServer: {
        open: true,
        contentBase: path.join(__dirname, `dist`),
        index: `index.html`
    },
    module:{
        rules:[{
            test:/.css$/,
            use: [`style-loader`, `css-loader`]  //執行loader的先後順序是從右到左,必須先執行css-loader
        }]
    }
};

理解 [`style-loader`, `css-loader`] 執行順序,就相當於 styleLoader( cssLoader( fileSource ) )

  • css-loader
主要用於把.css檔案的內容中@import/url()轉成js的匯入語法import/require並執行,輸入的是.css檔案內容,最後經常css-loader載入器處理後,得到的是css程式碼字串
  • style-loader
主要用於把css-loader處理後的css程式碼字串新增到頁面head內<style>中,但是通過js動態新增進去的

相關文章