Webpack3.x 通过Webpack加载Bootstrap的CSS/Scss/JS 及更改CSS样式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/stanxl/article/details/78645114

如何用webpack去加载bootstrap的css/scss 及JS呢,先准备一个bootstrap 模板b-index.html:

<!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><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-4">
                <p><img src=<%= require("./images/bootstrap.png")%>/></p>
            </div>
            <div class="col-md-8">
                <h1>Webpack 3 and Twitter Bootstrap</h1>
                <h2>How to configure Webpack 3 to load Twitter Bootstrap SCSS and JavaScript?</h2>
                <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
                    Launch demo modal
                </button>

                <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                    <div class="modal-dialog" role="document">
                        <div class="modal-content">
                            <div class="modal-header">
                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                                <h4 class="modal-title" id="myModalLabel">Modal title</h4>
                            </div>
                            <div class="modal-body">
                                <p>Some text goes here.</p>
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                                <button type="button" class="btn btn-primary">Save changes</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

</body>
</html>

要让这个模板中的bootstrap生效,先安装bootstrap-loader:

npm i -D bootstrap-loader

安装好后的当前版本是:

"bootstrap-loader": "^2.2.0"

安装过程中会提示需要安装resolve-url-loader与url-loader:

npm WARN bootstrap-loader@2.2.0 requires a peer of resolve-url-loader@* but none is installed. You must install peer dependencies yourself.
npm WARN bootstrap-loader@2.2.0 requires a peer of url-loader@* but none is installed. You must install peer dependencies yourself.

所以再把这两个loader也安装下:

npm i -D resolve-url-loader url-loader

安装后的当前版本分别:

"resolve-url-loader": "^2.2.0",
"url-loader": "^0.6.2"

再去安装bootstrap-sass:

npm install --save-dev bootstrap-sass

安装完成后的当前版本是:

"bootstrap-sass": "^3.3.7"

接下来去使用bootstrap-loader,在它的用法介绍里,可以使用配置的方式来进行,这里用的是bootstrap3 ,参考这里,需要先在根目录下新建一个.bootstraprc的文件:

---
# Output debugging info
# loglevel: debug

# Major version of Bootstrap: 3 or 4
bootstrapVersion: 3

# If Bootstrap version 3 is used - turn on/off custom icon font path
useCustomIconFontPath: false

# Webpack loaders, order matters
styleLoaders:
  - style
  - css
  - sass

# Extract styles to stand-alone css file
# Different settings for different environments can be used,
# It depends on value of NODE_ENV environment variable
# This param can also be set in webpack config:
#   entry: 'bootstrap-loader/extractStyles'
extractStyles: false
# env:
#   development:
#     extractStyles: false
#   production:
#     extractStyles: true


# Customize Bootstrap variables that get imported before the original Bootstrap variables.
# Thus, derived Bootstrap variables can depend on values from here.
# See the Bootstrap _variables.scss file for examples of derived Bootstrap variables.
#
# preBootstrapCustomizations: ./path/to/bootstrap/pre-customizations.scss


# This gets loaded after bootstrap/variables is loaded
# Thus, you may customize Bootstrap variables
# based on the values established in the Bootstrap _variables.scss file
#
# bootstrapCustomizations: ./path/to/bootstrap/customizations.scss


# Import your custom styles here
# Usually this endpoint-file contains list of @imports of your application styles
#
# appStyles: ./path/to/your/app/styles/endpoint.scss


### Bootstrap styles
styles:

  # Mixins
  mixins: true

  # Reset and dependencies
  normalize: true
  print: true
  glyphicons: true

  # Core CSS
  scaffolding: true
  type: true
  code: true
  grid: true
  tables: true
  forms: true
  buttons: true

  # Components
  component-animations: true
  dropdowns: true
  button-groups: true
  input-groups: true
  navs: true
  navbar: true
  breadcrumbs: true
  pagination: true
  pager: true
  labels: true
  badges: true
  jumbotron: true
  thumbnails: true
  alerts: true
  progress-bars: true
  media: true
  list-group: true
  panels: true
  wells: true
  responsive-embed: true
  close: true

  # Components w/ JavaScript
  modals: true
  tooltip: true
  popovers: true
  carousel: true

  # Utility classes
  utilities: true
  responsive-utilities: true

### Bootstrap scripts
scripts:
  transition: true
  alert: true
  button: true
  carousel: true
  collapse: true
  dropdown: true
  modal: true
  tooltip: true
  popover: true
  scrollspy: true
  tab: true
  affix: true

可以看到这里的这些属性大部分都为true,也就意味着,这些都会用到,但是有些是用不到的,后面会再进行优化,先保持这个样子。
还需要一个webpack.bootstrap.config.js的文件,在它里面配置了关于在不同的环境下,对bootstrap的处理不同:

const fs = require('fs');

function getBootstraprcCustomLocation() {
  return process.env.BOOTSTRAPRC_LOCATION;
}

const bootstraprcCustomLocation = getBootstraprcCustomLocation();

let defaultBootstraprcFileExists;

try {
  fs.statSync('./.bootstraprc');
  defaultBootstraprcFileExists = true;
} catch (e) {
  defaultBootstraprcFileExists = false;
}

if (!bootstraprcCustomLocation && !defaultBootstraprcFileExists) {
  /* eslint no-console: 0 */
  console.log('You did not specify a \'bootstraprc-location\' ' +
    'arg or a ./.bootstraprc file in the root.');
  console.log('Using the bootstrap-loader default configuration.');
}

// DEV and PROD have slightly different configurations
let bootstrapDevEntryPoint;
if (bootstraprcCustomLocation) {
  bootstrapDevEntryPoint = 'bootstrap-loader/lib/bootstrap.loader?' +
    `configFilePath=${__dirname}/${bootstraprcCustomLocation}` +
    '!bootstrap-loader/no-op.js';
} else {
  bootstrapDevEntryPoint = 'bootstrap-loader';
}

let bootstrapProdEntryPoint;
if (bootstraprcCustomLocation) {
  bootstrapProdEntryPoint = 'bootstrap-loader/lib/bootstrap.loader?extractStyles' +
    `&configFilePath=${__dirname}/${bootstraprcCustomLocation}` +
    '!bootstrap-loader/no-op.js';
} else {
  bootstrapProdEntryPoint = 'bootstrap-loader/extractStyles';
}

module.exports = {
  dev: bootstrapDevEntryPoint,
  prod: bootstrapProdEntryPoint,
};

以上参考的这里,这里很重要。同时在webpack.config.js中加入下面的代码针对dev 和 prot环境来使用bootstrap:

var bootstrapEntryPoints = require('./webpack.bootstrap.config.js');

var bootstrapConfig = isProt ? bootstrapEntryPoints.prod : bootstrapEntryPoints.dev;

并把bootstrapCofig添加到entry对象中:

entry: {
        app: "./src/app.js",
        anotherPage: "./src/anotherPage.js",
        bootstrap: bootstrapConfig
    },

此时去build,发现下面的error:

ERROR in ./node_modules/bootstrap-sass/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf
ERROR in ./node_modules/bootstrap-sass/assets/fonts/bootstrap/glyphicons-halflings-regular.woff2
ERROR in ./node_modules/bootstrap-sass/assets/fonts/bootstrap/glyphicons-halflings-regular.woff
ERROR in ./node_modules/bootstrap-sass/assets/fonts/bootstrap/glyphicons-halflings-regular.eot
ERROR in ./node_modules/bootstrap-sass/assets/fonts/bootstrap/glyphicons-halflings-regular.svg
Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type.

引起这些错误的原因是因为bootstrap中有Icon fonts需要加载,解决办法是需要再加两个rule:

{ test: /\.(woff2?|svg)$/, loader: 'url-loader?limit=10000' },
{ test: /\.(ttf|eot)$/, loader: 'file-loader' }

以上参考这里Icon fonts,再重新build后就可以看到下面的页面:

到这一步已经把Bootstrap的css加载进来,但是『Launch demo modal』这个button是不能用的,即JS还没有加载进来,在页面的控制台发现这样的error:

Uncaught ReferenceError: jQuery is not defined

在这里可以看到关于JQuery对bootstrap的更详细的说明,摘下来一段:

If you want to use Bootstrap's JS scripts — you have to provide jQuery to Bootstrap JS modules using imports-loader. To avoid having to include jQuery in your project you can disable all scripts (see scripts).

所以需要下面这段代码再添加到rules中:

// Bootstrap 3
{ test:/bootstrap-sass[\/\\]assets[\/\\]javascripts[\/\\]/, loader: 'imports-loader?jQuery=jquery' }

所以需要安装imports-loader和JQuery:

npm i -D imports-loader jquery

安装完成后的当前版本是:

"imports-loader": "^0.7.1",
"jquery": "^3.2.1"

再重新build后就可以看到『Launch demo modal』button点击后:

当运行生产模式时,可以看到生成的以hash值命名的Icon font:

如果想对这些fonts归档,放到一个文件下,可以像归档图片一样:

{ test: /\.(woff2?|svg)$/, loader: 'url-loader?limit=10000&name=fonts/[name].[ext]' },
            { test: /\.(ttf|eot)$/, loader: 'file-loader?name=fonts/[name].[ext]' }

对CSS也是一样:

new ExtractTextPlugin({
    filename: "./css/[name].css",
    disable: !isProt,
    allChunks: true
}),

重新build后:

以上基本结束了如何通过webpack去加载bootstrap的css及JS。

如果想要更改bootstrap的css,怎么做呢?可以这么做:
先到.bootstraprc文件中找到『preBootstrapCustomizations』,enabel这个属性,把它的value改成下面:

# Customize Bootstrap variables that get imported before the original Bootstrap variables.
# Thus, derived Bootstrap variables can depend on values from here.
# See the Bootstrap _variables.scss file for examples of derived Bootstrap variables.

preBootstrapCustomizations: ./src/bootstrap/pre-customizations.scss

去src目录下创建这个文件pre-customizations.scss,并把下面这个样式加进去:

$brand-success: #5cb85c !default;

在哪里可以找到这个bootstrap的样式呢,先把node_modules目录重新显示出来:『F1找到打开工作区设置』

{
    "files.exclude": {
        "**/.git": true,
        "**/.svn": true,
        "**/.hg": true,
        "**/CVS": true,
        "**/.DS_Store": true,
        "node_modules": true,
        ".vscode": true
      }
}

找到这个文件:/node_modules/bootstrap-sass/assets/stylesheets/bootstrap/_variables.scss就可以找到$brand-success,可以看到还有很多其他:

$brand-primary:         darken(#428bca, 6.5%) !default; // #337ab7
$brand-success:         #5cb85c !default;
$brand-info:            #5bc0de !default;
$brand-warning:         #f0ad4e !default;
$brand-danger:          #d9534f !default;

接下来需要把pre-customizations.scss import 到app.scss中:

@import './bootstrap/pre-customizations.scss';

把$brand-success赋给h1的color属性:

body{
    h1 {
        color: $brand-success;
    }
}

保存后重新build,就可以看到页面上的第一行已经变成了绿色:

猜你喜欢

转载自blog.csdn.net/stanxl/article/details/78645114