Webpack4 入門到帶你打包一個簡單單頁應用項目

正文前先吐槽下, webpack 對新手入門真的有點不友好,各個版本在配置上都有或多或少的差異,導致在對照各種教程學習的過程中免不了掉進各種坑里,所以寫這篇文章旨在簡單明了的解釋說明 webpack 的各種常用配置,希望能讓新人接觸 webpack 時少走些彎路。

一、搭建項目

1. 我們先新建一個項目 project 并用 npm 命令初始化項目(一路回車)
npm init
2. 安裝 webpack 與 webpack-cli ( 4 版本需要cli才能執行命令)
npm install --save-dev webpack webpack-cli
3. 新建 src 文件夾,存放我們要打包的源碼,默認輸入文件是 index.js,所以我們在 src 下新建一個index.js文件
document.write("測試文件打包")
4. 執行命令,便能實現最簡單的 “ 項目打包 ”
webpack
5. 輸入命令打包完成后會生成一個 dist 文件夾,里面就存放著我們需要打包的文件,這樣一個最簡單的 webpack 打包流程到此完工,接下來就要進入正片了。

二、命令部分

1. webpack 默認打包命令

第一部分我們使用過 webpack 命令進行打包,其實這個命令是不完整的,細心的小伙伴會發現執行時控制臺會有提示該命令有 production(生產) 與 development (開發)模式,完整命令如下:

// 兩個命令有和不同就請大家自己手動試一下,這里就不贅述了
webpack --mode production
webpack --mode development
2. webpack 根據配置文件打包命令

實際中我們打包項目根據需要會有各種配置,因此常用的是根據配置文件來進行打包,所以我們在項目根目錄下新建一個 webpack.conf.js 文件來保存配置信息

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
  }
}

稍后會對這個文件進行詳細講解,這里先執行命令看是否能成功進行按需打包

// webpack.conf.js 可根據自己需要命名 打包方法是 --config 配置文件路徑
webpack --mode production --config ./webpack.conf.js

打包成功會發現在 dist 下現在生成的文件名已經由默認變成了我們指定的 bundle.js

3. 改寫 npm 命令

由于 webpack 指令比較長,輸入時很不方便,我們有個小技巧可以簡化這一步驟,就是對項目的 package.json 文件中的 script 部分進行修改

  "scripts": {
    "dev": "webpack --mode development --config ./webpack.conf.js",
    "build": "webpack --mode production --config ./webpack.conf.js"
  },

然后執行以下命令就相當于執行了我們所設置對應的完整 webpack 命令

npm run dev
npm run build

三、配置部分

這部分會涉及很多內容,包括一些常用插件,我會逐步帶大家完善 webpack.conf.js 文件,但基本點到即止,詳細配置還需參考官方文檔自行配置

1. 關于文件路徑

配置文件會有許多關于文件路徑的設置,這方面一不小心就會出現問題,這里推薦采以下方法對相對路徑進行處理

const path = require('path')
// 此方法會根據傳入的相對路徑自動轉化為絕對路徑,確保路徑的正確
path.resolve(__dirname, '文件的相對路徑')
  • webpack.conf.js 配置例子
const path = require('path')

module.exports = {
  entry: path.resolve(__dirname, './src/index.js'),
  output: {
    filename: 'main.js',
  }
}

2. 配置文件結構總覽

主要包含以下 4 個部分
entry:配置文件入口
output:配置輸出文件名與路徑
plugins:配置引入的插件
module: 配置文件轉換的規則

const path = require('path')

module.exports = {
  // 輸入路徑配置
  entry: path.resolve(__dirname, './src/index.js'),
  // 輸出文件名和路徑配置
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, './dist')
  },
  // 引入插件配置
  plugins: [],
  // 文件類型轉換配置
  module: {}
}

對文件結構有個總體了解后我們接下來就開始逐步完善

3. 完善 js 文件輸出路徑

通常項目我們有一個專門的 js 文件夾進行存放 js 文件,并且為了區分版本,我們有時會使用 hash 進行區分( hash 值僅當源碼文件被修改時才會更新)

  • webpack.conf.js 配置例子
const path = require('path')

module.exports = {
  // 輸入路徑配置
  entry: path.resolve(__dirname, './src/index.js'),
  // 輸出文件名和路徑配置
  output: {
    // [name] 可自行配置,參考文檔
    // [hash:4] 使用 hash 取前 4 位
    filename: 'js/[name]-[hash:4].js',
    path: path.resolve(__dirname, './dist')
  },
  // 引入插件配置
  plugins: [],
  // 文件類型轉換配置
  module: {}
}

4. 使用插件,引入 html 模板

目前為止,我們打包的都只有 js 文件,作為前端項目,怎么可以沒有 html 文件呢,為了實現打包自動生成 html 文件,我們開始引入我們的第一個插件

  • 安裝插件 html-webpack-plugin
npm install --save-dev html-webpack-plugin
  • 在項目根目錄下新建 index.html 文件作為模板,供配置文件引入
  • webpack.conf.js 配置例子
const path = require('path')
const htmlWebpackPlugins = require('html-webpack-plugin')

module.exports = {
  // 輸入路徑配置
  entry: path.resolve(__dirname, './src/index.js'),
  // 輸出文件名和路徑配置
  output: {
    filename: 'js/main.js',
    path: path.resolve(__dirname, './dist')
  },
  // 引入插件配置
  plugins: [
    new htmlWebpackPlugins({
      // 輸出文件名
      filename: 'index.html',
      // 所引用模板文件位置
      template: 'index.html',
      // js 文件插入的位置
      inject: 'body'
    }),
  ],
  // 文件類型轉換配置
  module: {}
}

現在嘗試下打包,基本的 html 和 js 文件就有了,但這遠遠還不夠,我們還需要對 html 與 js 的相關配置進行處理,為了使項目更完整,我們還要新建一些文件。

5. 完善項目目錄

  • 在 src 目錄下新建 components 文件夾,分別新建 html, js, css 文件 ,下面以 scroll 組件為例

scroll.html

<div class="scroll">
  <p>scroll</p>
</div>

scroll.js

// import tpl from './scroll.html'
// import './scroll.css'

function scroll () {
  return {
    name: 'scroll',
    // tpl: tpl
  }
}

export default scroll

scroll.css

.scroll {
  height: 500px;
  width: 500px;
  background: red;
}

.scroll p {
  display: flex;
}
  • 文件新建完還需在我們的入口文件 index.js 中引入
import Scroll from './components/scroll'

const App = function () {
  var dom = document.getElementById('app')
  var scroll = new Scroll()
  dom.innerHTML = scroll.tpl
  document.write(scroll.name)
}

new App()
  • 最后修改下我們的 index.html 模板,新增 app 模塊
<!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>
</body>
</html>

這時嘗試打包,便可把我們新增的 scroll.js 引入進來了,但是這時我們 tpl 也就是 scroll.html 還處于注釋狀態,想要正確引入,還需添加其他插件

6. 使用插件,配對 .html 類型文件(之后的 .css, .png等其他類型的文件引入方法與此類似)

  • 安裝插件 html-loader
npm install --save-dev html-loader
  • 修改我們的 webpack.conf.js ,在 module 中完善我們的文件轉換配置
const path = require('path')
const htmlWebpackPlugins = require('html-webpack-plugin')

module.exports = {
  entry: path.resolve(__dirname, './src/index.js'),
  output: {
    filename: 'js/main.js',
    path: path.resolve(__dirname, './dist')
  },
  plugins: [
    new htmlWebpackPlugins({
      filename: 'index.html',
      template: 'index.html',
      inject: 'body'
    }),
  ],
  // 文件類型轉換配置
  module: {
    rules: [
      {
        // 正則匹配 html 文件
        test: /\.html$/,
        use: [
          {
            // 引入 html 文件加載插件
            loader: 'html-loader'
          }
        ]
      }
    ]
  }
}
  • 修改下我們的 scroll.js 文件,將之前的注釋取消
import tpl from './scroll.html'
// import './scroll.css'

function scroll () {
  return {
    name: 'scroll',
    tpl: tpl
  }
}

export default scroll
  • OK ~ 嘗試打包,現在應該就能正確的把 scroll.thml 的內容也打包進去了,成功之后我們就只剩 .css 類型文件沒有打包進去,那么繼續我們的配置

7. 使用插件,配對 .css 類型文件

  • 安裝插件 css-loader 與 style-loader
npm install --save-dev css-loader style-loader
  • 修改我們的 webpack.conf.js, 添加匹配規則
const path = require('path')
const htmlWebpackPlugins = require('html-webpack-plugin')

module.exports = {
  // 輸入路徑配置
  entry: path.resolve(__dirname, './src/index.js'),
  // 輸出文件名和路徑配置
  output: {
    filename: 'js/main.js',
    path: path.resolve(__dirname, './dist')
  },
  // 引入插件配置
  plugins: [
    new htmlWebpackPlugins({
      filename: 'index.html',
      template: 'index.html',
      inject: 'body'
    }),
  ],
  // 文件類型轉換配置
  module: {
    rules: [
      {
        // 正則匹配 html 文件
        test: /\.html$/,
        use: [
          {
            // 引入 html 文件加載插件
            loader: 'html-loader'
          }
        ]
      },
      {
        // 正則匹配 css 文件
        test: /\.css$/,
        use: [
          {
            // 引入 style 文件加載插件
            loader: 'style-loader'
          },
          {
            // 引入 css 文件加載插件
            loader: 'css-loader'
          }
        ]
      },
    ]
  }
}
  • 修改下我們的 scroll.js 文件,將之前 css 的注釋也取消
import tpl from './scroll.html'
import './scroll.css'

function scroll () {
  return {
    name: 'scroll',
    tpl: tpl
  }
}

export default scroll
  • 進行打包,成功后自己看看效果,這樣一個簡單 webpack 打包流程就已經走完了

至此,相信你對 webpack 的基本工作流程有了一定的了解,不過這只是剛剛開始,上面的例子離我們實際工作中的應用還有一段距離,例如 js 沒有實現 ES6 到 ES5 的轉換,css 樣式不是以一個文件的形式插入,遇到引入圖片文件時上面的配置會出現錯誤,還有許多我們常用的框架文件如 vue 等文件類型要打包時都是需要重新配置的,本文就不再對配置進行深究,只是簡單多介紹一些常用插件供大家學習了解

8. 插件介紹

  • babel-loader , babel-preset-latest , babel-core
    用于ES6 到 ES5 的轉換
  • autoprefixer , postcss-loader
    用于 css 根據配置的瀏覽器版本進行自動添加前綴
  • less, less-loader
    用于試別 less 類型樣式文件(sass等同理,引入相應插件進行配置)
  • url-loader
    用于加載圖片類型文件
  • image-webpack-loader
    用于優化圖片文件加載
  • mini-css-extract-plugin
    用于分離壓縮 css 文件
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容