Webpack:详解打包和管理JavaScript和CSS依赖

2025-04-02T15:51:34+08:00 | 5分钟阅读 | 更新于 2025-04-02T15:51:34+08:00

Macro Zhao

Webpack:详解打包和管理JavaScript和CSS依赖

推荐超级课程:

@TOC

Webpack是一个用于管理你的依赖项(css、js等)的构建工具。但为什么我们需要它呢?我们不是可以直接像下面这样将js和css添加到我们的html文件中吗?


<!doctype html>

<html lang="en">



<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

    <link rel="stylesheet" href="src/css/main.css">

    <link rel="stylesheet" href="src/css/first.css">

    <title>Webpack 2 Basics</title>

</head>



<body>

    <h1>Webpack basics</h1>

    <button id="button1">Press Me!</button>

    <script src="src/js/app.js"></script>

    <script src="src/js/first.js"></script>

    <script src="src/js/second.js"></script>

</body>



</html>

对于一个这样大小的应用程序,我们不需要管理js和css的依赖项,然而随着应用程序的增长,我们需要跟踪许多文件依赖项及其加载顺序。此外,代码压缩尚未实现。所以让我们通过使用webpack来改进我们的依赖管理。

在我们通过npm init初始化项目后,我们安装webpack


$npm init  

$npm i -D webpack

让我们在package.json文件中添加一个构建脚本


{

  "name": "webpack.basics",

  "version": "1.0.0",

  "description": "",

  "main": "index.js",

  "scripts": {

    "test": "echo \"Error: no test specified\" && exit 1",

    "build": "webpack --entry ./src/js/app.js --output-filename ./dist/bundle.js"

  },

  "author": "",

  "license": "ISC",

  "devDependencies": {

    "webpack": "^2.3.2",

    "webpack-dev-server": "^2.4.2"

  }

}

在这里,我们指定了webpack工作的入口文件,以便它通过依赖树进行操作。从app.js开始,webpack将所有代码合并到一个捆绑文件中,这里称为bundle.js。在文件中,我们需要使用“import”和“export”来显示依赖项。首先从app.js文件开始


import first from './first';



document.querySelector("#button1")

    .addEventListener("click", function () {

        first.handleClick()

    });

    

这表明app.js文件依赖于first.js。让我们来看看first.js文件


export default {

    handleClick() {

        alert("Hey, I was Pressed!!!");

    }

}

该文件导出了一个名为handleClick的函数。我们现在可以执行webpack脚本


$npm run build

正如您所看到的,webpack构建并创建了bundle.js。您应该有以下文件结构

我们现在删除js文件,并用一个捆绑文件替换它们


<!doctype html>

<html lang="en">



<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

    <link rel="stylesheet" href="src/css/main.css">

    <link rel="stylesheet" href="src/css/first.css">

    <title>Webpack 2 Basics</title>

</head>



<body>

    <h1>Webpack basics</h1>

    <button id="button1">Press Me!</button>

    <script src="dist/bundle.js"></script>

</body>



</html>

Webpack-Dev-Server

在上一节中,我们使用了文件协议在浏览器中渲染页面。我们不应该这样做。我们需要一个Web服务器来渲染页面。所以让我们安装webpack-dev-server。什么是webpack-dev-server?它是一个小型的express 服务器,围绕webpack及其所有功能进行封装。让我们安装webpack-dev-server。

@npm i -D webpack-dev-server

然后我们需要更改构建脚本以使用webpack-dev-server。

{
  "name": "webpack.basics",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack-dev-server --entry ./src/js/app.js --output-filename ./dist/bundle.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^2.3.2",
    "webpack-dev-server": "^2.4.2"
  }
}

再次运行脚本,注意页面现在托管在http://localhost:8080。此外,我们现在可以删除包含bundle.js文件的dist文件夹,应用程序仍然可以工作,因为webpack-dev-server会构建bundle.js文件并将其放入内存中。这非常方便,因为如果依赖树中的任何文件被更改,webpack-dev-server会自动重新构建捆绑文件并重新加载应用程序。

Webpack配置文件

为了充分利用webpack的功能,我们需要一个配置文件。配置文件将指示webpack如何处理我们的源文件。在项目的根目录中创建一个“webpack.config.js”。

var path = require("path");

module.exports = {
    entry: './src/js/app.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "bundle.js",
        publicPath: "/dist" //为webpack-dev-server模拟公共路径
    }
};

在运行构建脚本之前,我们需要从构建命令中删除选项,因为构建现在将使用配置文件来指示webpack该做什么。新的package.json应该如下所示:

{
  "name": "webpack.basics",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack-dev-server"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^2.3.2",
    "webpack-dev-server": "^2.4.2"
  }
}

加载器和插件

webpack的真正强大之处在于它提供的加载器和插件。

加载器是针对每个文件应用的任务,在webpack构建捆绑文件时运行。一个典型的任务是将sass文件预处理成css,并将输出加载到html文件的头部。

插件是在捆绑文件发送到输出文件之前应用的过程。一个典型的插件是压缩插件。为了说明加载器和插件,让我们从index.html中移除所有对css文件的引用,并从我们的入口文件(app.js)中导入css文件。为此,我们需要一些加载器和插件来进行转换。在这种情况下,我们需要两个加载器和一个插件:“css-loader”、“style-loader"和"extract-text-webpack-plugin”。


$npm i -D css-loader style-loader extract-text-webpack-plugin

现在我们需要告诉webpack使用这些加载器来分析css文件。


var path = require("path");

var ExtractTextPlugin = require("extract-text-webpack-plugin");



module.exports = {

    entry: './src/js/app.js',

    output: {

        path: path.resolve(__dirname, 'dist'),

        filename: "bundle.js",

        publicPath: "/dist" //模拟webpack-dev-server的公共路径

    },

    module: {

        rules: [

            {

                test: /\.css$/,

                use: ExtractTextPlugin.extract({

                    fallback: 'style-loader',

                    use: ['css-loader']

                })

            }

        ]

    },

    plugins: [

        new ExtractTextPlugin("bundle.css"),

    ]

};

这样做的目的是允许webpack将所有导入的css文件合并到一个名为"bundle.css"的包中。


import '../css/main.css';

import '../css/first.css';

import first from './first';



document.querySelector("#button1")

    .addEventListener("click", function () {

        first.handleClick()

    });

    

现在我们可以从index.html页面中移除css文件链接,并将其替换为对bundle.css文件的单一链接。

现在我们所有的css和js依赖都由webpack管理和处理。

为了实现额外的sass加载器,我们进行以下操作


var path = require("path");

var webpack = require("webpack");

var ExtractTextPlugin = require("extract-text-webpack-plugin");



module.exports = {

    entry: './src/js/app.js',

    output: {

        path: path.resolve(__dirname, 'dist'),

        filename: "js/bundle.js",

        publicPath: "dist"

    },

    module: {

        rules: [

            {

                test: /\.css$/,

                use: ExtractTextPlugin.extract({

                    fallback: 'style-loader',

                    use: ['css-loader'],

                })

            },

            {

                test: /\.scss$/,

                use: ExtractTextPlugin.extract({

                    fallback: 'style-loader',

                    use: ['css-loader', 'sass-loader'],

                })

            }

        ]

    },

    plugins: [

        new ExtractTextPlugin("css/bundle.css")

    ]

};

正如您所看到的,我们已经将包的路径更改为dist/css/bundle.css用于css和dist/js/bundle.js。最后,我们必须相应地调整index.html

© 2011 - 2025 Macro Zhao的分享站

关于我

如遇到加载502错误,请尝试刷新😄

Hi,欢迎访问 Macro Zhao 的博客。Macro Zhao(或 Macro)是我在互联网上经常使用的名字。

我是一个热衷于技术探索和分享的IT工程师,在这里我会记录分享一些关于技术、工作和生活上的事情。

我的CSDN博客:
https://macro-zhao.blog.csdn.net/

欢迎你通过评论或者邮件与我交流。
Mail Me

推荐好玩(You'll Like)
  • AI 动·画
    • 这是一款有趣·免费的能让您画的画中的角色动起来的AI工具。
    • 支持几十种动作生成。
我的项目(My Projects)
  • 爱学习网

  • 小乙日语App

    • 这是一个帮助日语学习者学习日语的App。
      (当然初衷也是为了自用😄)
    • 界面干净,简洁,漂亮!
    • 其中包含 N1 + N2 的全部单词和语法。
    • 不需注册,更不需要订阅!完全免费!
  • 小乙日文阅读器

    • 词汇不够?照样能读日语名著!
    • 越读积累越多,积跬步致千里!
    • 哪里不会点哪里!妈妈再也不担心我读不了原版读物了!
赞助我(Sponsor Me)

如果你喜欢我的作品或者发现它们对你有所帮助,可以考虑给我买一杯咖啡 ☕️。这将激励我在未来创作和分享更多的项目和技术。🦾

👉 请我喝一杯咖啡

If you like my works or find them helpful, please consider buying me a cup of coffee ☕️. It inspires me to create and share more projects in the future. 🦾

👉 Buy me a coffee