webpack

一、什么是 webpack

概念:webpack 是前端项目工程化的具体解决方案

主要功能:它提供了友好的前端模块化开发支持,以及代码压缩混淆处理浏览器端 JavaScript 的兼容性性能优化等强大的功能。

好处:让程序员把工作重心放到具体功能的实现上,提高了前端开发效率和项目的可维护性

注意:Vue 和 React 等前端项目,基本上都是基于 webpack 进行工程化开发的。

二、Webpack安装

1、全局安装

npm install -g webpack webpack-cli

2、 安装后查看版本号

webpack -v

三、初始化项目

1、创建webpack文件夹

进入webpack目录,执行命令

npm init -y

2、创建 src 文件夹

3、src 文件夹下创建 common.js

exports.info = function (str) {
    document.write(str);
}

4、src下创建utils.js

exports.add = function (a, b) {
    return a + b;
}

5、src下创建main.js

const common = require('./common');
const utils = require('./utils');
common.info('Hello world!' + utils.add(100, 200));

四、JS打包

1、webpack目录下创建配置文件webpack.config.js

以下配置的意思是:读取当前项目目录下src文件夹中的main.js(入口文件)内容,分析资源依赖,把相关的js文件打包,打包后的文件放入当前目录的dist文件夹下,打包后的js文件名为bundle.js

const path = require("path"); //Node.js内置模块
module.exports = {
    entry: path.join( __dirname, './src/main.js'), //配置入口文件
    // mode:(development/production) 既 开发模式/生产模式(发布模式)
    mode: 'development',
    output: {
        // 输出路径,__dirname:当前文件所在路径
        path: path.join( __dirname, './dist'),
        filename: 'bundle.js' //输出文件
    }
}

2、命令行执行编译命令

webpack #有黄色警告
webpack --mode=development #没有警告
#执行后查看bundle.js 里面包含了上面两个js文件的内容并惊醒了代码压缩

也可以配置项目的npm运行命令,修改 package.json 文件

"scripts": {
    //...,
    "dev": "webpack"
 }

运行npm命令执行打包

npm run dev

3、webpack 目录下创建 index.html

引用bundle.js

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

4、浏览器中查看index.html

五、CSS打包(loader)

1、安装 style-loader 和 css-loader

Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。

Loader 可以理解为是模块和资源的转换器。

首先我们需要安装相关Loader插件,css-loader 是将 css 装载到 javascript;style-loader 是让 javascript 认识 css(需要在项目里安装

npm install --save-dev style-loader css-loader

// 或者分开安装
npm install style-loader

npm install css-loader

2、修改 webpack.config.js

const path = require("path"); //Node.js内置模块
module.exports = {
    //...,
    output:{...},
    module: {
        rules: [  
            {  
                test: /\.css$/,    //打包规则应用到以css结尾的文件上
                use: [{loader: 'style-loader'}, {loader: 'css-loader'}]
            }  
        ]  
    }
}

3、在src文件夹创建 style.css

body{
    background:pink;
}

4、修改main.js

在第一行引入style.css

require('./style.css');

5、重新运行打包

npm run dev

6、关于 less

安装:

npm install less-loader

修改 webpack.config.js

const path = require("path"); //Node.js内置模块
module.exports = {
    //...,
    output:{...},
    module: {
        rules: [  
            {  
                test: /\.css$/,    //打包规则应用到以css结尾的文件上
                use: [{loader: 'style-loader'}, {loader: 'css-loader'}]
            },
            {  
                test: /\.less$/,    //打包规则应用到以css结尾的文件上
                use: [{loader: 'style-loader'}, {loader: 'css-loader'}, {loader: 'less-loader'}]
            },
        ]  
    }
}

7、关于 图片导入(在js中导入并动态赋于属性值src)

base64 的图片可以防止发起不必要的网络请求,但大图片不建议转换成 base64 格式的(如轮播图)。

import logo from "./src/image/logo.jpg"

img.src = logo;

安装

npm install url-loader file-loader

配置

module: {
    rules: [
        { test: /\.jpg|png|gif$/, use: {loader: 'url-loader?limit=20480'} }
    ]
}

// ?limit=20480
// 这个是用来规定 url-loader 的临界值是多少,一旦对于这个临界值,就不会转换图片格式为 base64,单位是 字节(1kb = 1000字节)

六、插件

每次修改代码后向要看效果都需要重新打包一次,这样子显得很繁琐,可以通过插件来解决这个麻烦。

6.1 webpack-dev-server 插件

6.1.1 安装

每当修改了源代码,webpack 会自动进行项目的打包和构建。

npm instll -D webpack-dev-server

6.1.2 配置 webpack-dev-server

在 package.json 文件的 “scripts” 属性中,添加一个运行方法,如 dev-serve

"dev-serve": "webpack serve"

// 运行命令时输入 npm run dev-serve

6.1.3 webpack-dev-serve 端口配置

webpack serve 的默认端口是 8080,但有时候这个端口被占用了的可能性很大,所以需要重新配置

webpack.config.js

在 mode 同级上添加 devServer 配置

// 监听文件改动,自动打包
//  watch: true,
devServer: {
    static: path.join(__dirname, './'), // 指定发布后的映射的路径,./代表映射当前路径
    compress: true, // 压缩资源
    port: 9000, // 指定服务器的端口号
    open: 'Chrome', // 指定以哪个浏览器打开,open:true 代表以默认浏览器打开
}

6.2 html-webpack-plugin 插件

该插件的基本作用就是生成html文件

  • 通过 HTML 插件复制到项目中的 index.html 页面,也被放到内存中(既并不是真正意义上的的复制)
  • HTML 插件在生成的 index.html 页面,自动注入了打包的 bundle.js 文件

6.2.1 安装

npm install html-webpack-plugin

6.2.2 配置

webpack.config.js

// 1. 导入 HTML 插件,得到一个构造函数
const HtmlPlugin = require("html-webpack-plugin")

// 2.创建 HTML 插件的实例对象
const htmlPlugin = new HtmlPlugin({
    template: "./src/index.html",   // 得到原文件的存放路径
    filename: "./index.html",    // 指定生成的文件的存放路径
})

module.export = {
    mode: "development",
    ....,
    plugins: [htmlPlugin],   // 3. 通过 plugins 节点,使 htmlPlugin 插件生效
}

小技巧

有时候想导入文件的时候,路径关系是一个很麻烦的事情,但如果使用 webpack 的简单配置,就能解决这个问题。

webpack.config.js 文件下与 module 同一级别中添加 resolve 配置

module.exports = {
    mode: "development",
    module: {...},
    resolve: {
        alias: {
            // 告诉 webpack,@ 符号表示 src 这一层目录
            '@': path.join(__dirname, './src/')
        }
    }
}

当需要导入 src/js/test.js 文件的时候,只需要

import test from "@/js/test.js"

七、babel-loader

webpack 只能打包处理一部分高级的 JavaScript 语法。对于那些 webpack 无法处理的高级 js 语法,需要借助于 babel-loader 进行打包处理。例如 webpack 无法处理下面的 JavaScript 代码:

class Person {
    // webpack 无法打包处理“静态属性 static”这个高级语法
    static indo = 'person info'
}

console.log(Person.info)

7.1 安装 babel-loader 相关的包

npm install babel-loader @babel/core @babel/plugin-proposal-class-properties
  • babel-loader
  • @babel/core
  • @babel/plugin-proposal-class-properties

7.2 配置 babel-loader

在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:

{
    test: /\.js$/,
    exclude: /node_modules/, // 排除 node_modules 文件
    use: {
        loader: 'babel-loader',
        options: {
            // 声明一个 babel 插件,此插件用来转化 class 中的高级语法
            plugins: ['@babel/plugin-proposal-class-properties']
        }
    }
}

八、项目打包发布

8.1 为什么要打包发布

项目开发完成之后,使用 webpack 对项目进行打包发布的主要原因有以下两点:

  • 开发环境下,打包生成的文件存放于内存中,无法获取到最终打包生成的文件
  • 开发环境下,打包生成的文件不会进行代码压缩和性能优化

8.2 配置 webpack 的打包发布

package.json 文件的 script 节点下,新增 build 命令如下:

“script”: {
    "dev": "webpack serve", // 开发环境中,运行 dev 命令
    "build": "webpack --model production" // 项目发布时,运行 build 命令
}

–model 是一个参数项,用来指定 webpack 的运行模式。production 代表生产环境,会对打包生成的文件进行代码压缩性能优化

注意:通过 –model 指定的参数项,会覆盖 webpack.config.js 中的 model 选项

8.3 将 JavaScript 文件统一生成到 js 目录中

webpack.config.js 配置文件的 output 节点中,进行如下的配置:

output: {
    path: path.join(__dirname, 'dist'),
    // 明确告诉 webpack 把生成的 bundle.js 文件存放到 dist 目录下的 js 子目录中
    filename: 'js/bundle.js'
}

8.4 把图片文件统一生成到 image 目录中

修改 webpack.config.js 中的 url-loader 配置项,新增 outputPath 选项既可指定图片文件的输出路径

{
    test: /\.jpg|png|gif$/,
    use: {
        loader: 'url-loader',
        options: {
            limit: 22228,
            // 明确指定把打包生成的图片,存储到 dist 目录下的 image 文件夹中
            outputPath: "image"
        }
    }
}

8.5 自动清理 dist 目录下的旧文件

为了在每次打包发布时自动清理掉 dist 目录中的旧文件,可以安装并配置 clean-webpack-plugin 插件:

安装

npm install clean-webpack-plugin

webpack.config.js

// 导入
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const cleanPlugin = new CleanWebpackPlugin()

// 挂载
plugins: [htmlPlugin, cleanPlugin]

九、Source Map