Webpack 打包 Bootstrap

编辑于2018年03月06日

今年 1 月份 Bootstrap 4 姗姗来迟,这次更新可以说非常巨大,几乎涉及到了每一行代码。主要变化有:

  • 从 Less 迁移到了 Sass。
  • 改进了网格系统,默认使用 Flexbox。
  • 使用 rem 取代了 px。
  • 提供了新的 Card 组件。
  • 不支持 IE8、IE9 和 iOS 6。
  • 重写了 JavaScript 插件。
  • 更多新特性……

看到这么多变化,让人忍不住想要去尝试一下。正好最近打算集中时间完成 Ghost 的主题,于是我决定基于 Bootstrap 4 进行主题的开发。

以前,在使用 Bootstrap 时都是下载编译好的版本或者直接使用 CDN 链接,然后通过优先级更高地选择器覆盖默认样式,这非常的简单。但是这次,我想尝试通过 npm 包来安装 Bootstrap,通过修改 Sass 变量的方式来修改默认样式,并使用 Webpack 打包项目。

我时常忘记 Webpack 的一些配置,所以决定写一篇博客记录下这一过程,便于日后回顾。

安装依赖

因为我之前完成了一些 Ghost 主题项目的初始化操作,这里就直接从安装依赖开始了,这和平时初始化项目没什么不同,主要涉及一些主题开发需要的文件。

Bootstrap 依赖了 jQueryPopper。同时,插件需要按需手动引入,如果用到了插件,那么还需要安装 exports-loader。由于我目前没有用到插件,因此就没有安装 export-loader。

$ yarn add bootstrap jquery popper.js

除了上述项目依赖外,还有各种开发依赖,主要是 webpack 的 loaders 和 plugins。

$ yarn add autoprefixer babel-core babel-loader babel-preset-env clean-webpack-plugin css-loader extract-text-webpack-plugin node-sass postcss-flexbugs-fixes postcss-loader sass-loader style-loader -D

既然是使用 Webpack 打包,当然就还需要安装 Webpack,我使用的是 Webpack 3(Webpack 4 还没折腾)。

$ yarn add webpack@^3.11.0 -D

配置 Webpack

配置文件内容如下,具体配置的含义这里就不进行介绍了。

const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const autoprefixer = require('autoprefixer');

module.exports = {
  entry: {
    vendor: ['jquery', 'popper.js', 'bootstrap'],
    poppy: './src/js/index.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'assets')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve(__dirname, 'src'),
        use: ['babel-loader?cacheDirectory=true']
      }, {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [{
            loader: 'css-loader',
            options: { minimize: true }
          }, {
            loader: 'postcss-loader',
            options: {
              indent: 'postcss',
              plugins: () => [
                require('postcss-flexbugs-fixes'),
                autoprefixer({
                  browsers: [
                    '>1%',
                    'last 4 versions',
                    'Firefox ESR'
                  ],
                  flexbox: 'no-2009'
                })
              ]
            }
          }, {
            loader: 'sass-loader'
          }]
        })
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin({
      filename: '[name].css',
      allChunks: true
    }),
    new webpack.ProvidePlugin({
      $: 'jquery', // Used for Bootstrap JavaScript components
      jQuery: 'jquery', // Used for Bootstrap JavaScript components
      Popper: ['popper.js', 'default'] // Used for Bootstrap dropdown, popup and tooltip JavaScript components
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: Infinity
    }),
    new webpack.optimize.UglifyJsPlugin(),
    new CleanWebpackPlugin(['assets'])
  ]
};

使用 Bootstrap

Bootstrap 4 使用 Sass,支持通过修改 Sass 变量的方式改变默认的样式。为此,我创建了两个文件 main.scss_custom.scss,其中 _custom.scss 用来修改 Sass 变量,main.scss 则作为入口样式文件。文件内容如下:

// main.scss

@import "custom";
@import "~bootstrap/scss/bootstrap";
// _custom.scss

$primary: #fa541c;

接着,我们在项目入口文件中导入 Bootstrap JavaScript 和 scss 文件即可:

import 'bootstrap';
import '../scss/main.scss';

完成上面两个步骤之后,就可以像之前使用编译好的文件或者 CDN 链接加载一样使用 Bootstrap 了。