Bootstrap4默認樣式不對胃口?教你使用NPM+Webpack+SASS來定製

Bootstrap 是一個流行的前端樣式庫,可以方便快速的構建應用,但默認樣式可能不盡人意,本文就介紹如何使用 NPM, Webpack, SASS 針對它的源碼來定製自己的主題。版本使用的是 Bootstrap v4.3.1。

本文提供了一個使用此方式編寫的一個後臺管理模板 Dunwoo Admin,文末有獲取源碼的方式。演示地址:https://dunwoo.com/projects/dunwoo-admin

Dunwoo Admin

安裝 Node.js

Webpack 是對前端資源進行打包和編譯的工具,它依賴於 Node.js,首先介紹下如何配置和安裝綠色版的 Node.js。

下載綠色版本:https://nodejs.org/en/download/ (以 node-v10.16.1-win-x64.zip 爲例)

並解壓到某個目錄下,比如 D:\node-v10.16.1, 然後設置系統環境變量:

NODE_HOME=D:\node-v10.16.1
NODE_PATH=%NODE_HOME%\node_modules
path=增加;%NODE_HOME%;

在 Node.js 主目錄新建 node_global 和 node_cache 兩個目錄,並使用以下命令設置 npm 全局安裝模塊的位置以及下載緩存路徑:

npm config set prefix "D:\node-v10.16.1\node_global"
npm config set cache "D:\node-v10.16.1\node_cache"

最後,可以在命令行使用 node -v 和 npm -v 驗證是否安裝成功。

Webpack 安裝和配置

安裝 Webpack 之前,需要使用 npm init 在項目根目錄生成一個 package.json 文件,它類似 Java 中 Maven 的 pom.xml, 用於描述項目的元信息,名稱、版本等,更重要的是它指定了項目運行依賴的模塊,下面就是本項目此文件的內容:

{
  "name": "dunwoo-admin",
  "version": "1.0.0",
  "description": "Bootstrap 4 Theme",
  "author": "wskwbog",
  "license": "MIT",
  "private": true,
  "keywords": [],
  "scripts": {
    "build": "webpack --progress --colors",
    "dev": "webpack-dev-server --inline --devtool eval-source-map --progress",
    "start": "npm run dev"
  },
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/plugin-proposal-object-rest-spread": "^7.3.2",
    "@babel/preset-env": "^7.3.1",
    "autoprefixer": "^9.4.7",
    "babel-loader": "^8.0.6",
    "css-loader": "^3.2.0",
    "node-sass": "^4.12.0",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^7.2.0",
    "style-loader": "^1.0.0",
    "webpack": "^4.39.2",
    "webpack-cli": "^3.3.7",
    "webpack-dev-server": "^3.8.0",
    "mini-css-extract-plugin": "^0.8.0",
    "clean-webpack-plugin": "^3.0.0"
  },
  "dependencies": {
    "bootstrap": "^4.3.1",
    "jquery": "^3.3.1",
    "popper.js": "^1.14.7"
  }
}

其中關鍵配置的意義是:

  • scripts: 配置不同功能腳本命令的縮寫,可以使用 npm run build|dev 簡單方便的調用
  • devDependencies: 指定項目開發所需要的模塊
  • dependencies: 指定項目運行所依賴的模塊

配置好 package.json 後就可以在當前目錄運行 npm install 依賴的模塊就會下載到當前目錄的 node_modules 目錄中。

在開始使用 Webpack 之前,還要進行一些配置,這也是比較麻煩的地方,本項目的 webpack.config.js 配置內容如下:

// 引入 node 相關模塊
const path = require('path');

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  mode: 'development',
  devtool: 'source-map',
  entry: {
    theme: './src/js/theme.js' // 入口文件
  },
  output: { // 打包輸出目錄
    path: path.resolve(__dirname, './dist/'),
    filename: 'js/[name].js'
  },
  devServer: { // 本地開發服務器
    contentBase: './dist/',
    host: '0.0.0.0',
    port: 3000,
    writeToDisk: true
  },
  module: {
    rules: [{
      test: /(\.jsx|\.js)$/, // 正則匹配 .jsx 或 .js 後綴的文件
      loader: 'babel-loader',
      exclude: /node_modules/
    }, {
      test: /\.(scss)$/, // 正則匹配 .scss 後綴的文件
      use: [{
        // loader: 'style-loader', // inject CSS to page
        loader: MiniCssExtractPlugin.loader,
        options: {
          // publicPath: '../',
          // hmr: process.env.NODE_ENV === 'development',
        },
      }, {
        loader: 'css-loader', // translates CSS into CommonJS modules
      }, {
        loader: 'postcss-loader', // Run postcss actions
        options: {
          plugins: function () { // postcss plugins, can be exported to postcss.config.js
            return [
              require('autoprefixer')
            ];
          }
        }
      }, {
        loader: 'sass-loader' // compiles Sass to CSS
      }]
    }]
  },
  plugins: [
    new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns:['js/*', 'css/*']
    }),
    new MiniCssExtractPlugin({
      filename: 'css/[name].css',
      chunkFilename: 'css/[id].css',
    })
  ]
}

接下來分析下各配置項的作用。

entry/output

entry: {
  theme: './src/js/theme.js'
},
output: {
  path: path.resolve(__dirname, './dist/'),
  filename: 'js/[name].js'
},

入口(entry)和出口(output)的配置比較簡單,指定了從哪個模塊開始構建以及將編譯結果輸出目的地。其中 **__dirname** 表示 webpack.config.js 所在的目錄。

webpack-dev-server

通常開發的過程是:

  1. 修改 scss 樣式
  2. 然後命令行運行 npm run build 編譯
  3. 最後刷新頁面看效果

這幾步完全可以自動化,Webpack 就提供了一個本地開發 Web 服務器 webpack-dev-server, 它可以監聽代碼的改動並自動編譯和發佈,基本配置如下:

devServer: {
  contentBase: './dist/', // 資源根目錄
  host: '127.0.0.1', // 綁定主機 IP 
  port: 3000, // 監聽端口
  writeToDisk: true // 將編譯結果寫到磁盤
},

更多配置項可參考:https://webpack.js.org/configuration/dev-server/

接下來就是 Webpack 兩個比較重要概念的配置, Loader 和 Plugin:

  • Loader: 編譯和轉換模塊源碼,比如將 scss 編譯成 css, 將 ES6 轉爲 JS, 將 JSX 文件轉成 JS 文件等等
  • Plugin: 用於解決 Loader 無法實現的功能,比如清理,打包優化和壓縮等等

Babel

Bootstrap 4 使用 ES6 重寫了所有的 JS 組件,而 Babel 就是一個 JavaScript 編譯器,它可以將使用 ES6 語法編寫的文件,轉成瀏覽器兼容的 JS 文件。在 package.json 中與它相關的模塊如下:

  • @babel/core: Babel 編譯的核心
  • @babel/preset-env: 爲每個環境預設的 Babel
  • babel-loader: 結合使用 Babel 和 webpack 編譯 JavaScript
  • @babel/plugin-proposal-object-rest-spread: 支持 ES6 擴展運算符(...)

與把它相關的配置文件通常會放到一個名爲 .babelrc.js 的文件中:

module.exports = {
  presets: [
    [
      '@babel/env',
      {
        loose: true,
        modules: false,
        exclude: ['transform-typeof-symbol']
      }
    ]
  ],
  plugins: [
    '@babel/plugin-proposal-object-rest-spread'
  ]
};

CSS 模塊

Webpack 提供了兩個 Loader 來處理樣式,css-loaderstyle-loader,二者處理的任務不同:

  • css-loader: 解析 @import 和 url() 方法,實現類似 import/require() 的功能
  • style-loader: 將樣式加入到頁面中,與 css-loader 結合使用可以把樣式嵌入到 webpack 打包後的 JS 文件中

CSS 預處理器比如 Sass 對原生 CSS 進行了擴展,添加了變量,函數等特性,使得 css 的編寫更加靈活,Webpack 配置以下兩個 Loader 後就能直接使用:

  • sass-loader: 將 scss 編譯成 css
  • postcss-loader: 主要使用 autoprefixer 添加瀏覽器前綴

具體配置可查看上文的 webpack.config.js, 有一點需要注意的是: 高版本的 autoprefixer, 支持的瀏覽器配置通常放在 .browserslistrc 文件中。

mini-css-extract-plugin

將 CSS 提取爲獨立文件的插件,爲每個包含 CSS 的 JS 文件創建一個 CSS 文件,支持 CSS 和 SourceMaps 的按需加載,依賴 Webpack 4 以上的版本。

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              // 指定資源路徑, 默認與 webpackOptions.output 相等
              publicPath: '../',
              // 模塊熱加載相關配置
              hmr: process.env.NODE_ENV === 'development',
            },
          },
          'css-loader',
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // all options are optional
      filename: '[name].css',
      chunkFilename: '[id].css',
      ignoreOrder: false, // Enable to remove warnings about conflicting order
    }),
  ],
};

更多配置項可參考:https://webpack.js.org/plugins/mini-css-extract-plugin/

clean-webpack-plugin

Webpack 構建之前用於刪除和清理構建文件夾的插件,這個插件有個屬性 cleanOnceBeforeBuildPatterns 可以配置哪些文件和文件夾要刪除,哪些不刪除,一個簡單的示例如下:

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
    plugins: [
      new CleanWebpackPlugin({ // 只清理 js 和 css 目錄中的文件
        cleanOnceBeforeBuildPatterns:['js/*', 'css/*']
      }),
    ],
};

更多配置項可參考:https://www.npmjs.com/package/clean-webpack-plugin

Bootstrap 主題定製方法

定製 Bootstrap 4 主題有兩個方法,一是直接修改源碼,但這樣後續不好升級;二是修改它提供的 SCSS 變量靈活定製,這樣對源碼沒有侵入性,可以在不觸及核心文件的情況下完全重新設計 Bootstrap 4 的樣式。項目文件的基本結構如下:

dunwoo-admin/
├── .babelrc.js
├── .browserslistrc
├── .gitignore
├── package.json
├── webpack.config.js
├── README.md
├── src/
│   ├── scss/
│   │   ├── base/
│   │   ├── pages/
│   │   ├── partials/
│   │   ├── utilities/
│   │   ├── vendor/
│   │   └── _theme.scss
│   ├── js/
│   │   ├── modules/
│   │   ├── vendor/
│   │   └── theme.js
│   │── fonts/
│   └── img/
└── dist/
    ├── css/
    │   └── theme.css
    ├── js/
    │   └── theme.js
    ├── img/
    ├── fonts/
    └── libs/

其中主要的 Sass 文件就是 src/scss/_theme.scss:

@charset "utf-8";
// 覆蓋原設計樣式的變量
@import "base/variables-theme";
// bootstrap 核心源碼
@import "../../node_modules/bootstrap/scss/bootstrap";
// 自定義組件的樣式
@import "base/variables";
@import "base/general";

@import "partials/menubar";
@import "partials/navbar";
@import "partials/card";
@import "partials/widget";
@import "partials/timeline";

@import "pages/signin";

@import "utilities/utilities";

一個簡單修改主題顏色變量的方法是:

$theme-colors: (
  "primary":    #2c7be5,
  "secondary":  #95aac9,
  "success":    #00d97e,
  "info":       #39afd1,
  "warning":    #f6c343,
  "danger":     #e63757,
  "light":      #f8f9fa,
  "dark":       #3b506c
);

在項目根目錄執行 npm run build 就能在頁面看到修改結果。

小結

本文只是對 webpack 簡單的使用,對於前端目前也正在學習,如有錯誤歡迎指出交流。

源碼可從 GitHub 鏈接下載,https://github.com/dwosc/dunwoo-admin

或者關注微信公衆號「頓悟源碼」回覆關鍵詞「Bootstrap」 獲取百度網盤下載鏈接。

主題將會不斷更新優化,歡迎關注!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章