likes
comments
collection
share

webpack -- 第一节课:简介、安装、基础配置

作者站长头像
站长
· 阅读数 8

webpack官网 webpack.p2hp.com/

webpack简介

webpack是一个打包模块化JavaScript的工具,他会从入口模块出发,识别出源码中的模块化导入语句,递归地找出入口文件的所有依赖,将入口和其他所有的依赖打包到一个单独的文件中

webpack是基于node.js使用的工具

webpack -- 第一节课:简介、安装、基础配置 webpack的能力

编译代码能力,提高效率,解决浏览器兼容问题

webpack -- 第一节课:简介、安装、基础配置

 模块整合能力,提高性能,可维护性,解决浏览器频繁请求文件的问题 

webpack -- 第一节课:简介、安装、基础配置

 万物皆可模块能力,项目维护性增强,支持不同种类的前端模块类型,统一的模块化方案,所有资源文件的加载都可以通过代码控制 

webpack -- 第一节课:简介、安装、基础配置

webpack安装

  • 可以安装全局,但是不建议安装全局,不利于版本更新

  • 可以安装早项目里,命令如下:

# webpack安装在项目里
# 安装最新的稳定版本
npm i -D webpack

#安装指定版本
npm i -D webpack@<version>

#安装最新版的体验版,会出现bug,不可以用于生产换将
npm i -D webpack@beta

#安装webpack V4+版本时,需要额外安装webpack-cli
npm i -D webpack-cli

补充: -D 开发依赖 -S 生产依赖

如果是做普通前端项目,package.json 里面的依赖包作为开发依赖和生产依赖基本没啥区别;如果项目是做 npm 包或者 node 服务的,会有些许差别。

  • 开发依赖

  1. 执行操作后,package.json 里 devdependencies 里保存相应依赖包,这些包只在做项目的时候会使用到,在项目打包上线后不依赖于这些包项目依然可以正常运行。比如:gulp/webpack 等等。
  2. 在举个例子:比如说在nodejs中的开发阶段我想要通过爬虫向我这个里面数据库里面放点东西,实际上这个东西打包上线之后用户根本就不会用到这个东西,只是我们开发人员在开发时候的使用,这个就是开发依赖.
  • 生产依赖

执行操作后,package.json 里 dependencies 里保存相应依赖包,这些包在项目打包上线后依然需要使用项目才能正常运行,比如:axios 等等

准备执行构建

  1. 初始化项目 webpack -- 第一节课:简介、安装、基础配置

  2. 准备入口文件:新建src文件夹,并在文件夹下新建index.js文件 webpack -- 第一节课:简介、安装、基础配置

  3. 新建文件webpack.config.js文件,并简单配置webpack webpack -- 第一节课:简介、安装、基础配置

  4. 终端执行 npx webpack 命令,结果会生成dist文件夹,其中的main.js文件是项目代码经webpack处理后得到的文件 注意:webpack执行构建会找webpack.config.js这个配置文件,如果没有找到,走默认配置 webpack -- 第一节课:简介、安装、基础配置

  5. 在dist文件夹下新增index.html文件,并引入main.js文件 webpack -- 第一节课:简介、安装、基础配置

  6. 浏览器执行index.html文件,可以看到项目运行结果 webpack -- 第一节课:简介、安装、基础配置

webpack基础配置和理解

//webpack.config.js

const path = require("path");

// webpack 是基于nodeJS的,webpack配置就是module.exports抛出的对象,
module.exports = {
    // context -- 上下文,项目打包的相对路径,默认值:process.cwd(),必须是绝对目录
    context:process.cwd(), // 项目文件夹的根目录

    // entry -- 入口 执行构建的入口,项目入口
    // 从入口文件开始,将所有的依赖、代码等解析压缩到一个文件里
    // entry 可以是字符串,数组,对象
    entry:'./src/index.js', // --> 实际:entry:{ main:"./src/index.js", }
    // entry:['./src/index.js','./src/other.js'], // 并非多入口,只是将两个模块的代码放在了一个文件里
    // entry:{   
    //     index:'./src/index.js',
    //     other:'./src/other.js',
    // }, // 多入口,更改 --- output.filename:[name].js
          // 意思是:从index.js文件开始执行的代码会在打包后存在index.js文件中
          // 从other.js文件开始执行的代码会在打包后存在other.js文件中
    
    // 输出
    output:{
        // path -- 构建后的文件资源存放的地方,必须是绝对路径
        path:path.resolve(__dirname,"./dist"),

        // filename -- 构建后的文件资源名字
        filename:"main.js", // 文件会被dist文件夹下的index.html引用,之后直接执行index.html文件,就可以使项目在浏览器上执行
        // filename:"[name].js", // 多出口 配合 entry 多入口使用,不同的html文件引用不同的执行文件,就可以执行两套代码了
                                 // 比如:other.html文件引用other.js文件,执行代码1;index.html文件引用index.js文件,执行代码2;
    }
}
// other.js
export function add(n1,n2){
    return n1 + n2;
}
// index.js

// 模块化开发,当前流行的单页面入口应用 spa
// 引入模块,形成依赖
import { add } from "./other.js";
console.log(add(2,3));

执行 npx webpack 命令后,src/main.js文件内容如图 webpack -- 第一节课:简介、安装、基础配置

webpack执行过程:

  1. 寻找webpack.config.js文件,如果有按照配置解析入口文件,如果没有按照默认配置解析文件
  2. 找到entry配置的入口文件
  3. 入口文件第一行代码:import { add } from "./other.js",将add函数引入到方法内存里
  4. 入口文件第二行代码:console.log(add(2,3));
    • 先执行add(2,3),得出结果5,并替换内容
    • 将console.log(add(2,3));编译为console.log(5);
  5. 入口代码结束,解析后的代码被放入新的文件main.js文件中。
  6. 按照webpack配置的出口文件内容,在目录下新建dist文件,并在dist文件下放入main.js文件。

webpack 中 hash 的作用,以及如何利用 hash 实现不停机更新

Webpack 中的 Hash

在 Webpack 的构建流程中,hash 是一个重要的概念。hash 是一个特殊的字符串,它是根据文件的内容计算得出的。在 Webpack 中,有三种不同类型的 hash:hash,chunkhash 和 contenthash。

  • hash:是根据整个项目构建的,当项目中的任何一个文件内容改变,整个项目的 hash 值都会改变。
  • chunkhash:根据不同的入口文件(Entry)进行依赖文件解析、构建,对应不同的 chunk,最后每个 chunk 根据内部模块的内容和依赖关系构建出一个 hash 值。只要组成 chunk 的文件内容或其依赖的文件内容发生改变,那么构建的 hash 值就会改变,用于存在两个或以上的入口文件的项目。
  • contenthash:根据文件的内容进行 hash 计算,只有文件内容改变,这个 hash 值才会改变。

在实际的构建过程中,我们通常会将这些 hash 值添加到打包输出的文件名中,这样一来,只要文件的内容发生改变,那么文件名就会改变,从而达到浏览器缓存管理的目的。

如何利用 Hash 实现不停机更新

利用 Hash 实现不停机更新主要是利用浏览器的缓存机制和服务器配置。

在 Webpack 打包的时候,如果我们在配置中设置了 output 的 filename 为 '[name].[contenthash].js',那么每次构建出的文件名就会带上基于文件内容计算出的 hash 值。只要我们的代码有改动,那么打包出的新文件的文件名就会变化。

当用户访问网站的时候,服务器会返回包含这些静态资源链接的 HTML 文件。因为每次更新的文件名不同,所以用户浏览器会重新请求新的文件,而不是使用旧的缓存文件。而旧的文件如果没有被请求,也不会影响网站的正常使用。

要注意的是,这需要服务器配置长时间的静态资源缓存,并且在发布新版本时,要保证新旧版本文件同时存在,从而实现无缝切换,也就是我们说的“不停机更新”。

这种方式不仅可以利用浏览器缓存,提高网站性能,也可以在更新网站的时候不影响用户的使用体验。

filename:"[name][hash:16].js"
// hash:哈希值默认20位 hash:16 -- 16位哈希值

mode构建模式

mode:模式配置,用于指定Webpack的工作模式。包括开发模式(development)和生产模式(production)。

loader 模块转换

webpack默认只支持.json和.js模块,不支持其他的不认识的模块。

// 处理不认识的模块
module:{
    rules:[
        {
            test:/\.css$/,
            // loader 模块转换
            // loader的执行顺序是从后往前
            // css-loader 言简意赅 是把css模块的内容 加入到 js模块中去
            // css in js方式
            // style-loader 从js中提取css的loader 在html中创建style标签 把css的内容放在这个style标签中
            use:["style-loader","css-loader"],
        }
    ]
}

常见的 loader:

  • image-loader:加载并且压缩图片文件
  • css-loader:帮助 webpack 打包处理 css 文件,使用 css-loader 必须要配合使用 style-loader
  • style-loader:用于将 css 编译完成的样式,挂载到页面的 style 标签上。但是要注意 loader 执行顺序,style-loader 要放在第一位,loader 都是从后往前执行
  • babel-loader:把 ES6 转换成 ES5
  • sass-loader: css 预处理器,能更好的编写 css
  • postcss-loader: 用于补充 css 样式在各种浏览器的前缀,很方便,不需要手动写了
  • eslint-loader: 用于检查代码是否符合规范,是否存在语法错误
  • url-loader: 处理图片类型资源,可以根据图片的大小进行不同的操作,如果图片大小大于指定大小,则将图片进行资源打包,否则将图片转换为 base64 格式字符串,再把这个字符串打包到 JS 文件里

第一节课全部配置:

const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

// webpack 是基于nodeJS的,webpack配置就是module.exports抛出的对象,
module.exports = {
    // context -- 上下文,项目打包的相对路径,默认值:process.cwd(),必须是绝对目录
    context:process.cwd(), // 项目文件夹的根目录

    // entry -- 入口 执行构建的入口,项目入口
    // 从入口文件开始,将所有的依赖、代码等解析压缩到一个文件里
    // entry 可以是字符串,数组,对象
    entry:'./src/index.js', // --> 实际:entry:{ main:"./src/index.js", }
    // entry:['./src/index.js','./src/other.js'], // 并非多入口,只是将两个模块的代码放在了一个文件里
    // entry:{   
    //     index:'./src/index.js',
    //     other:'./src/other.js',
    // }, // 多入口,更改 --- output.filename:[name].js
          // 意思是:从index.js文件开始执行的代码会在打包后存在index.js文件中
          // 从other.js文件开始执行的代码会在打包后存在other.js文件中
    
    // 输出
    output:{
        // path -- 构建后的文件资源存放的地方,必须是绝对路径
        path:path.resolve(__dirname,"./dist"),

        // filename -- 构建后的文件资源名字
        // filename:"main.js", // 文件会被dist文件夹下的index.html引用,之后直接执行index.html文件,就可以使项目在浏览器上执行
        filename:"[name]-[hash:16].js", // 多出口 配合 entry 多入口使用,不同的html文件引用不同的执行文件,就可以执行两套代码了
                                 // 比如:other.html文件引用other.js文件,执行代码1;index.html文件引用index.js文件,执行代码2;
                                 // hash:哈希值默认20位 hash:16 -- 16位哈希值
    },
    // 构建模式:none  生产模式--production 开发模式--development
    mode:"development",
    // 处理不认识的模块
    module:{
        rules:[
            {
                test:/\.css$/,
                // loader 模块转换
                // loader的执行顺序是从后往前
                // css-loader 言简意赅 是把css模块的内容 加入到 js模块中去
                // css in js方式
                // style-loader 从js中提取css的loader 在html中创建style标签 把css的内容放在这个style标签中
                use:["style-loader","css-loader"],
            },
        ]
    },
    // 插件 这个机制原理是作用于webpack整个打包周期的
    // CleanWebpackPlugin 清除冗余的打包文件
    plugins:[new CleanWebpackPlugin()],
}
转载自:https://juejin.cn/post/7346947729711792179
评论
请登录