webpack的使用


张登友,张登友的博客,张登友的网站——

初始化项目

mkdir webpack && cd webpack # 创建并切换目录
npm init -y # 初始化目录

初始化完成之后,打开刚才自动生成的package.json,添加如下内容:

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

并安装如下依赖:

npm i webpack webpack-cli webpack-dev-server --save-dev

在index.js文件添加内容

console.log('hello');

之后运行

npm run start

此时便会自动生成dist目录,里面会有一个main.js文件

webpack配置文件

前面提到,我们可以更改webpack的配置的。为了配置webpack,我们需要在根目录创建一个webpack.config.js文件。这是一个js文件,所以我们可以在里面写任意可运行的js代码。 首先更改入口文件和出口文件:

// webpack.config.js
const path = require("path");
module.exports = {
    mode: "development", // "production" | "development"
      // 选择 development 为开发模式, production 为生产模式

    // 将入口文件指定为src目录下的index.js
    entry: {index: path.resolve(__dirname, "src", "index.js")}, //指定入口文件

    // 将输出文件目录改为build/
    output: {
        path: path.join(__dirname, "build"), //指定输出路径
        filename: 'main.js' //指定输出文件名
    }
};

添加html页面

html-webpack-plugin的作用就是改变webpack的工作方式,使webpack可以将打包后的js文件,添加到html页面中。首先,安装插件:

npm i html-webpack-plugin --save-dev

接着更改webpack.config.js,添加配置

const HtmlWebpackPlugin = require("html-webpack-plugin"); //引入HTML处理模块

module.exports = {//添加plugins字段部分
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "src", "index.html")
        })
    ]    
}

此时webpack.config.js的完整配置文件如下

// webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
      mode: "development", // "production" | "development"
      // 选择 development 为开发模式, production 为生产模式

    // 将入口文件指定为src目录下的main.js
    entry: {index: path.resolve(__dirname, "src", "index.js")},
    // 将输出文件目录改为build/
    output: {
        path: path.join(__dirname, "build"),
        filename: 'main.js'
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "src", "index.html")
        })
    ] 
};

在原来的src目录下新建一个html文件,此处我并未引入script文件

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <meta name="Keywords" content="定义关键词" />
    <meta name="Description" content="定义页面描述" />
</head>

<body>
    <p>hello world</p>
</body>

</html>

此时再次运行

npm run start

build目录下会自动生成index.html文件,这是经过压缩的HTML文件,并且自动引入了main.js文件

build

所以,我们可以总结html-webpack-plugin的功能:

  1. 加载html文件。
  2. 将webpack打包后的js文件,通过script标签添加到html文件中。

webpack本地服务

作为开发者,肯定会用到本地服务,webpack提供了development server,可以很方便的启动一个本地服务,方便开发者进行开发工作。 首先我们需要安装webpack-dev-server包。

首先安装本地服务插件

npm i webpack-dev-server --save-dev

接着修改package.json文件的script部分

"scripts": {
  "start": "webpack",
  "dev": "webpack serve --mode development", // 开发模式
  "pdc": "webpack serve --mode production" // 生产模式
},

并在webpack.config.js部分新增如下字段

devServer:{
    port: 8000, //定义启动端口
    static: path.join(__dirname,'build') //定义启动文件路径
}

这时候我们再运行

# 启动命令
npm run dev
# 停止命令服务按Ctrl+C

server

浏览器访问localhost:8000即可看到我们打包后的页面了

加载css

需要用到webpack loaders(处理各种各样的模块和文件)。加载css文件,需要安装至少如下两个loaders:

  • css-loader: 让我们可以使用import语句导入css文件。
  • style-loader: 将css样式插入到html dom中。

安装命令

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

接着在webpack.config.js添加如下字段

module: {
    rules: [{
        test: /\.css$/, //正则匹配以.css结尾的文件
        use: ["style-loader", "css-loader"] //使用模块(刚刚安装的两个)
    }]
}

注:loaders的顺序很重要,webpack加载loaders的顺序是从右到左

因为style-loader负责将样式插入到html中,程序总是先执行js代码,所以首先执行的是css的import,所以顺序错误了。

然后在入口文件index.js文件中添加如下字段

import "./style.css";

此时我们再访问localhost:8000,发现字体颜色也已经改变

我们可以再使用命令再生成一次文件

npm run start

此时html文件并未有style.css文件引入,但是通过浏览器访问后看见,字体也是红色的,css样式也已经成功加载,这是因为webpack将css一并打包进main.js文件了,我们可以通过打包后的main.js源码看见

css_loader

加载sass

# 安装命令
npm install sass-loader sass webpack --save-dev

新建一个sass文件并添加样式

p
    font-size: 30px

在index.js添加

import "./style.sass";

在webpack.config.js添加

{
    test: /\.s[ac]ss$/i, //正则匹配sass和scss
    use: [
        // 将 JS 字符串生成为 style 节点
        'style-loader',
        // 将 CSS 转化成 CommonJS 模块
        'css-loader',
        // 将 Sass 编译成 CSS
        'sass-loader',
    ],
}

最后使用npm run start生成文件并用浏览器访问localhost:8000,此时sass文件的样式已成功加载

sass-loader

加载babel-loader

使用babel-loader,首先安装

npm install -D babel-loader @babel/core @babel/preset-env

需要按照es6标准编译,那么你就安装一个 babel-preset-es2015, 同样,如果你要按照es7来编译,那么你就安装babel-preset-es2016:

npm install babel-preset-es2016 --save-dev

一般来说,如果想用最新的规范做编译,直接安装babel-preset-env就可以了,它包含了 babel-preset-es2015, babel-preset-es2016, and babel-preset-es2017,等价于babel-preset-latest,可以编译所有最新规范中的代码:

npm install babel-preset-env --save-dev

然后在webpack.config.js的model部分添加如下字段

{
  test: /\.m?js$/,
  exclude: /(node_modules|bower_components)/,
  use: {
      loader: 'babel-loader',
      options: {
          presets: ['@babel/preset-env', //也可以写成presets:['env']
              // {
              //     targets: {
              //         browser: ['> 1%'] //babel做编译的时候,编译出来的语法支持所有市场占有率超过1%的浏览器,把参数变成chrome,那么打包出的代码,只能保证在chrome上运行正常,其他浏览器能不能跑就不好说了,因为你配置的打包程度就是兼容chrome即可。
              //     }
              // }
          ]
      }
  }
}

另一种做法是在项目的根目录下新建一个.babelrc文件,内容如下:

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

新建测试文件es6.js

// es6.js
const fn2 = (a, b) => {
    return a + b;
};
console.log(fn2(1, 2));

然后运行命令生成文件即可

npm run start

完整配置文件

文件夹结构如下

.
├── build
│   ├── index.html
│   └── main.js
├── node_modules
├── package-lock.json
├── package.json
├── src
│   ├── es6.js
│   ├── index.html
│   ├── index.js
│   ├── style.css
│   └── style.sass
└── webpack.config.js
// webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    mode: "development", // "production" | "development"
    // 选择 development 为开发模式, production 为生产模式
    // 将入口文件指定为src目录下的main.js
    entry: {
        index: path.resolve(__dirname, "src", "index.js")
    },
    // 将输出文件目录改为build/
    output: {
        path: path.join(__dirname, "build"),
        filename: 'main.js'
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "src", "index.html")
        })
    ],
    devServer: {
        port: 8000,
        static: path.join(__dirname, 'build')
    },
    module: {
        rules: [{
                test: /\.css$/,
                use: ["style-loader", "css-loader"]
            },
            {
                test: /\.s[ac]ss$/i,
                use: [
                    // 将 JS 字符串生成为 style 节点
                    'style-loader',
                    // 将 CSS 转化成 CommonJS 模块
                    'css-loader',
                    // 将 Sass 编译成 CSS
                    'sass-loader',
                ],
            },
            {
                test: /\.m?js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                    presets: ['@babel/preset-env', //也可以写成presets:['env']
                        // {
                        //     targets: {
                        //         browser: ['> 1%'] //babel做编译的时候,编译出来的语法支持所有市场占有率超过1%的浏览器,把参数变成chrome,那么打包出的代码,只能保证在chrome上运行正常,其他浏览器能不能跑就不好说了,因为你配置的打包程度就是兼容chrome即可。
                        //     }
                        // }
                        ]
                    }
                }
            }
        ]
    }
};
// package.json
{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack",
    "dev": "webpack serve --mode development",
    "pdc": "webpack serve --mode production"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "webpack-cli": "^4.9.1"
  },
  "devDependencies": {
    "@babel/core": "^7.16.10",
    "@babel/preset-env": "^7.16.10",
    "babel-loader": "^8.2.3",
    "css-loader": "^6.5.1",
    "html-webpack-plugin": "^5.5.0",
    "sass": "^1.49.0",
    "sass-loader": "^12.4.0",
    "style-loader": "^3.3.1",
    "webpack": "^5.66.0",
    "webpack-dev-server": "^4.7.3"
  }
}

一键安装命令(仅适用于上面用到的插件,HTML,js,css,sass/scss)

npm i webpack webpack-cli webpack-dev-server html-webpack-plugin webpack-dev-server css-loader style-loader sass-loader sass babel-loader @babel/core @babel/preset-env --save-dev

一些概念

入口文件(entry point)

webpack工作开始的地方,就是一个js文件。webpack通过这个文件内的import,收集其他模块文件,在通过其他模块文件内的import语句,收集其他依赖,最后将所有模块文件打包到一起,形成一个整体可运行的代码。 默认的入口文件是 src/index.js

输出文件(output)

output就是webpack通过build过程打包后形成的文件。默认的输出文件夹为根目录下的dist/文件夹。

加载器(loaders)

loaders是一些第三方扩展包,可以帮助webpack处理加载各种类型的文件。例如有处理css、image文件的loaders。如果没有loaders,webpack本身是不支持css文件的。

插件(plugins)

plugins也是第三方插件,它可以改变webpack的工作方式,例如有些插件可以设置webpack的环境变量。

模式(mode)

webpack有两种工作方式:development(开发模式)和production(生产模式)。 主要的区别就是production模式下,产生的捆绑包(文件)更小,去掉了在运行下无关的注释,空格等等。这样可以加快用户加载代码的速度。

参考以下文档

官方文档

webpack快速入门2021


文章作者: 张登友
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 张登友 !
  目录