webpack:从入门到真实项目配置

简单使用

安装

在命令行中依次输入

mkdir  webpack-demo
cd webpack-demo
// 创建 package.json,这里会问一些问题,直接回车跳过就行
npm init 
//  推荐这个安装方式,当然你也安装在全局环境下
// 这种安装方式会将 webpack 放入 devDependencies 依赖中
npm install --save-dev webpack

然后按照下图创建文件

在以下文件写入代码

// sum.js
// 这个模块化写法是 node 环境独有的,浏览器原生不支持使用
module.exports = function(a, b) {
    return a + b
}
// index.js
var sum = require('./sum')
console.log(sum(1, 2))
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <script src="./build/bundle.js"></script>
</body>
</html>

现在我们开始配置最简单的 webpack,首先创建 webpack.config.js 文件,然后写入如下代码

// 自带的库
const path = require('path')
module.exports = {
    entry:  './app/index.js', // 入口文件
    output: {
      path: path.resolve(__dirname, 'build'), // 必须使用绝对地址,输出文件夹
      filename: "bundle.js" // 打包后输出文件的文件名
    }
  }

现在我们可以开始使用 webpack 了,在命令行中输入

node_modules/.bin/webpack

没问题的话你应该可以看到类似的样子

可以发现原本两个 JS 文件只有 100B,但是打包后却增长到 2.66KB,这之中 webpack 肯定做了什么事情,我们去 bundle.js 文件中看看。

把代码简化以后,核心思路是这样的

var array = [(function () {
        var sum = array[1]
        console.log(sum(1, 2))
    }),
    (function (a,b) {
        return a + b
    })
]
array[0]() // -> 3

因为 module.export 浏览器是不支持的,所以 webpack 将代码改成浏览器能识别的样子。现在将 index.html 文件在浏览器中打开,应该也可以看到正确的 log。

我们之前是在文件夹中安装的 webpack,每次要输入 node_modules/.bin/webpack 过于繁琐,可以在 package.json 如下修改

"scripts": {
    "start": "webpack"
  },

然后再次执行 npm run start,可以发现和之前的效果是相同的。简单的使用到此为止,接下来我们来探索 webpack 更多的功能。

Loader

Loader 是 webpack 一个很强大功能,这个功能可以让你使用很多新的技术。

Babel

Babel 可以让你使用 ES2015/16/17 写代码而不用顾忌浏览器的问题,Babel 可以帮你转换代码。首先安装必要的几个 Babel 库

npm i --save-dev babel-loader babel-core babel-preset-env

先介绍下我们安装的三个库

  • babel-loader 用于让 webpack 知道如何运行 babel
  • babel-core 可以看做编译器,这个库知道如何解析代码
  • babel-preset-env 这个库可以根据环境的不同转换代码

接下来更改 webpack-config.js 中的代码

module.exports = {
// ......
    module: {
        rules: [
            {
            // js 文件才使用 babel
                test: /\.js$/,
             // 使用哪个 loader
                use: 'babel-loader',
            // 不包括路径
                exclude: /node_modules/
            }
        ]
    }
}

配置 Babel 有很多方式,这里推荐使用 .babelrc 文件管理。

// ..babelrc
{
    "presets": ["babel-preset-env"]
}

现在将之前 JS 的代码改成 ES6 的写法

// sum.js
export default (a, b) => {
    return a + b
}
// index.js
import sum from './sum'
console.log(sum(1, 2))

执行 npm run start,再观察 bundle.js 中的代码,可以发现代码被转换过了,并且同样可以正常 输出3。

当然 Babel 远不止这些功能,有兴趣的可以前往官网自己探索。

处理图片

这一小节我们将使用 url-loader 和 file-loader,这两个库不仅可以处理图片,还有其他的功能,有兴趣的可以自行学习。

先安装库

npm i --save-dev url-loader file-loader

创建一个 images 文件夹,放入两张图片,并且在 app 文件夹下创建一个 js 文件处理图片
,目前的文件夹结构如图

// addImage.js
let smallImg = document.createElement('img')
// 必须 require 进来
smallImg.src = require('../images/small.jpeg')
document.body.appendChild(smallImg)

let bigImg = document.createElement('img')
bigImg.src = require('../images/big.jpeg')
document.body.appendChild(bigImg)

接下来修改 webpack.config.js 代码

module.exports = {
// ...
    module: {
        rules: [
            // ...
            {
            // 图片格式正则
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                use: [
                  {
                    loader: 'url-loader',
                    // 配置 url-loader 的可选项
                    options: {
                    // 限制 图片大小 10000B,小于限制会将图片转换为 base64格式
                      limit: 10000,
                    // 超出限制,创建的文件格式
                    // build/images/[图片名].[hash].[图片格式]
                      name: 'images/[name].[hash].[ext]'
                   }
                  }
                ]
            }
        ]
    }
  }

运行 npm run start,打包成功如下图

可以发现大的图片被单独提取了出来,小的图片打包进了 bundle.js 中。

在浏览器中打开 HTML 文件,发现小图确实显示出来了,但是却没有看到大图,打开开发者工具栏,可以发现我们大图的图片路径是有问题的,所以我们又要修改 webpack.config.js 代码了。

module.exports = {
    entry:  './app/index.js', // 入口文件
    output: {
      path: path.resolve(__dirname, 'build'), // 必须使用绝对地址,输出文件夹
      filename: "bundle.js", // 打包后输出文件的文件名
      publicPath: 'build/' // 知道如何寻找资源
    }
    // ...
  }

最后运行下 npm run start,编译成功了,再次刷新下页面,可以发现这次大图被正确的显示了。下一小节我们将介绍如何处理 CSS 文件。

处理 CSS 文件

添加 styles 文件夹,新增 addImage.css 文件,然后在该文件中新增代码

img {
    border: 5px black solid;
}
.test {border: 5px black solid;}

这一小节我们先使用 css-loader 和 style-loader 库。前者可以让 CSS 文件也支持impost,并且会解析 CSS 文件,后者可以将解析出来的 CSS 通过标签的形式插入到 HTML 中,所以后面依赖前者。

npm i --save-dev css-loader style-loader

首先修改 addImage.js 文件

import '../styles/addImage.css'

let smallImg = document.createElement('img')
smallImg.src = require('../images/small.jpeg')
document.body.appendChild(smallImg)

// let bigImg = document.createElement('img')
// bigImg.src = require('../images/big.jpeg')
// document.body.appendChild(bigImg)

然后修改 webpack.config.js 代码

module.exports = {
// ...
    module: {
      rules: [
        {
            test: /\.css$/,
            use: ['style-loader',
                {
                    loader: 'css-loader',
                    options: {
                        modules: true
                       }
                }
            ]
        },
      ]
    }
  }

运行下 npm run start,然后刷新页面,可以发现图片被正确的加上了边框,现在我们来看一下 HTML 的文件结构

从上图可以看到,我们在 addImage.css 文件中写的代码被加入到了 style 标签中,并且因为我们开启了 CSS 模块化的选项,所以 .test 被转成了唯一的哈希值,这样就解决了 CSS 的变量名重复问题。

但是将 CSS 代码整合进 JS 文件也是有弊端的,大量的 CSS 代码会造成 JS 文件的大小变大,操作 DOM 也会造成性能上的问题,所以接下来我们将使用 extract-text-webpack-plugin插件将 CSS 文件打包为一个单独文件

首先安装 npm i --save-dev extract-text-webpack-plugin

然后修改 webpack.config.js 代码

const ExtractTextPlugin = require("extract-text-webpack-plugin")

module.exports = {
// ....
    module: {
      rules: [
        {
          test: /\.css$/,
          // 写法和之前基本一致
          loader: ExtractTextPlugin.extract({
          // 必须这样写,否则会报错
                fallback: 'style-loader',
                use: [{
                    loader: 'css-loader',
                    options: { 
                        modules: true
                    }
                }]
            })
        ]
        }
      ]
    },
    // 插件列表
    plugins: [
    // 输出的文件路径
      new ExtractTextPlugin("css/[name].[hash].css")
    ]
  }

运行下 npm run start,可以发现 CSS 文件被单独打包出来了

但是这时候刷新页面会发现图片的边框消失了,那是因为我们的 HTML 文件没有引用新的 CSS 文件,所以这里需要我们手动引入下,在下面的章节我们会通过插件的方式自动引入新的文件。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值