Webpack & 基础入门以及接入 CSS、Typescript、Babel

一、什么是 Webpack

Webpack 是一款 JS 模块化开发的技术框架,其运作原理是将多个 JS 文件关联起来构成可运行的应用程序。

Webpack 拥有丰富的 plugins / loaders 插件生态圈,可以让 js 识别不同的语言如 .css, .scss, .sass, .json, .xml, .ts, .vue, .tsx 等等,这也让 Webpack 至今仍然在许多项目中仍有一席之地。

尽管现在的构建工具百花齐放,如 vite, vue-cli, craco, esbuild, glup, rollup

但大部分构建工具的许多概念基本都是相通的,我认为学习 webpack 依然是前端人员必学技能之一。

二、使用 Webpack

2.1 准备工作

  1. 新建案例项目 webpack-example

  2. 安装 Webpack

bash 复制代码
mkdir webpack-example && cd webpack-example
yarn init -y
yarn add webpack webpack-cli -D

当前 Webpack 版本:5.88.2

  1. 新建目录&文件
bash 复制代码
mkdir src && cd src && touch index.js
cd ../ && touch index.html

结构如下:

2.2 编译&打包

这里分几个步骤:

  1. index.js 代码改造:
js 复制代码
const sayHi = () => {
  alert('Hello, webpack!')
}
sayHi()
  1. package.json 配置 webpack 脚本并执行。
json 复制代码
"scripts": {
    "build": "webpack"
  },

构建后的产物默认会放在 dist 目录。

  1. index.html 引入产物
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./dist/main.js"></script>
</head>
<body>
  
</body>
</html>

本地 server 打开 index.html 即可:

你可能会问,这和直接引入 src/index.js 有何区别?别急,还没体现 webpack 能力呢。

继续改造:

  1. src/ 新增 date.js & tools.js 俩文件 ,内容如下:
js 复制代码
// src/date.js
export const getDate = () => {
  return new Date().toLocaleDateString()
}
// src/tools.js
export const add = (a, b) => {
  return a + b
}
  1. 在 src/index.js 中引入:
js 复制代码
// 引入👇
import { getDate } from './date'
import { add } from './tools'

const run = () => {
  console.log('The date is: ', getDate())
  console.log('10 + 20 is equal', add(10, 20))
}
run()
  1. 重新 build

    可以看到 date.js 和 tools.js 被一起打包进 main.js 文件,模块化开发概念有没有逐渐涌现出来?

三、接入 CSS

截至目前,我们依旧未使用 webpack 配置的能力,仅通过一个 build 命令。

现在开始思考下,在不依赖 webpack 的情况下,js 中引入 css 文件可行?

当然没问题,现代浏览器基于 ES6 语法可以直接引入 css 文件。

但你会发现引入后抛出 MIME 错误,这是因为它只负责请求,不负责非 JS 响应资源处理。

下面用 webpack 配置来解决。

3.1 准备工作

  1. 安装依赖包:
bash 复制代码
yarn add style-loader css-loader -D

解释:css-loader 将 css 内容打包成 CommonJS ,style-loader 引入 CommonJS 并将其插入到页面 style 中,这两个是必不可少的。

3.1 配置&使用

  1. 项目新建 webpack.config.js 文件,内容如下:
js 复制代码
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
};

解释:rules 作为引入 loader 的入口,test 表示要处理匹配的文件后缀名。
rules 的选项还有很多,这里仅以最简单的方式作为演示。

use 执行顺序从最后开始: css-loader -> style-loader 。

  1. src/ 新增 index.css 文件,样式如下:
css 复制代码
body {
	background-color: cyan;
}
  1. src/index.js 引入
js 复制代码
// ...
import './index.css'
// ...
  1. 调整 package.json build 脚本,指定配置:
json 复制代码
"scripts": {
    "build": "webpack --config=webpack.config.js"
  },
  1. 重新 build 即可看到效果:

在 dist/ 产物中可以看到,css 样式是通过 JS 插上去的,你可能会问,这和在 index.html 中直接引入 css 有何不同?

关于这个问题,我想说如果是 100 个 css 呢?毕竟一个项目的 css 文件数量是非常多的。

再比如像 scss, less 这些 CSS 预处理语言的文件呢,总不可能手动引入吧?

还是得靠 webpack ,只需引入对应的插件和 loader 即可;为了让 webpack 入门纯粹点,这里不再详细赘述。

四、接入 Typescript

随着越来越多的项目引入 TS,似乎就成了前端必学的"新语言"~

如果还没用过 Typescript 的同学可参考:TypeScript 日常基本语法 再回头看本文。

4.1 准备工作

  1. 安装依赖包
bash 复制代码
yarn add typescript ts-loader -D

解释:typescript 是一款专门将 ts 编译成 js 的工具,本身可以独立存在,而 ts-loader 充当 typescript 与 webpack 之间的信号传递者。

4.2 配置&使用

  1. webpack.config.js 中配置如下:
js 复制代码
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
      // 新增👇
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/, // 不处理 node_modules 。
      },
    ],
  },
  resolve: {
    // 调整后缀解析优先级。
    extensions: ['.ts', '.tsx', '.js'],
  },
};

提示:配置 extensions 的原因是,Webpack 默认以 src/index 作为编译入口,再根据默认后缀优先级顺序: ['js', 'json', '.wasm'] 开始解析,为了避免解析现有的 index.js,这里要手动调整 extensions ,当然也可以设置 entry ,这里先不演示,后面会讲到。

  1. src/下新增 index.ts 文件,内容如下:
js 复制代码
import { getDate } from './date'
import { add } from './tools'
import './index.css'
// 这里用 TS 提供的 void 语法作为测试。
const run = (): void => {
  console.log('The date is: ', getDate())
  console.log('10 + 20 is equal', add(10, 20))
}
run()
  1. 重新 build,效果和原来一样:

五、接入 Babel

balbel 是一款是专门将 JS 高级语法编译为可执行的低版本语法编译器,比如 ES6/7/8 -> ES5。

如果还没用过的同学可参考:JS & 介绍 Babel 的使用及 presets & plugins 的概念 再回头看文本。

5.1 准备工作

  1. 安装依赖:
bash 复制代码
yarn add babel-loader @babel/core @babel/preset-env -D

解释:

  • @babel/core 是编译 JS 的核心逻辑,即编译器。

  • @babel/preset-env 基于编译器,集成了各种插件,比如 es6 -> es5, class -> prototype,链式 ?. 语法等。

- balbel-loader 充当 @babel/core 与 webpack 之间的信号传递者。

5.2 配置&使用

  1. webpack.config.js
js 复制代码
module.exports = {
  // 新增:开启本地调试模式,让产物不要压缩。
  mode: 'development',
  // 新增:指定编译入口,避免与上章节的 index.ts 冲突。
  entry: './src/index.js',
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
      // 新增:
      {
        test: /\.(?:js|ts)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              ['@babel/preset-env']
            ]
          }
        }
      }
    ],
  },
};
  1. index.js 中使用高版本语法作为演示,比如 ES6 的 const 声明关键字:
js 复制代码
const run = () => {
  console.log('The date is: ', getDate())
  console.log('10 + 20 is equal', add(10, 20))
}
run()
  1. 重新 build,在 dist/main.js 源码中便可看到 const 被转成了 var

5.3 babel 兼容 ts

  1. 先将 entry 引入为 ./src/index.ts
js 复制代码
// webpack.config.js
...
entry: './src/index.ts',
...
  1. src/index.ts 语法如下,这里用 void 作为演示:
js 复制代码
import './index.css'
const run = (): void => {
  const obj = { num: 100 }
  console.log('Hello, webpack', obj?.num === 100)
}
run()
  1. 执行 build
bash 复制代码
yarn build

你会发现 babel 并不识别 .ts 文件,直接报错了:

这是因为 babel 默认仅支持 JS,对于 TS 还得单独处理:

  1. 安装 Babel 插件:
bash 复制代码
 yarn add @babel/preset-typescript -D

解释:

  • babel/preset-typescript 是基于 babel-core 编译器实现出来的插件,就是让 babel 可识别 .ts 后缀。

注意:插件本身不负责编译 ts -> js,仅仅对 ts 源码以 js 的角度来进行转换处理。

  1. 引入插件:
js 复制代码
module.exports = {
  mode: 'development',
  entry: './src/index.ts',
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.(?:js|ts)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              [
                '@babel/preset-env',
              ],
              // 新增:
              [
                '@babel/preset-typescript',
              ]
            ],
          }
        }
      }
    ],
  },
};
  1. 重新 build 即可:

F Q A

4.1 Webpack 和 Babel 有什么区别?

咋一看,Webpack 和 Babel 好像都能编译 JS?这两者间有何区别呢?其实区别还是蛮大的:

  1. Webpack 就像一位 JS 文件管理者,拥有着大量的处理不同文件&产物的插件圈,最终将各种文件联起来形成页面应用。
  2. Babel 可以将 JS 代码编译为可向下兼容运行的低版本代码,它也有着丰富的插件圈,但它们是专门与 js 源码打交道的,这也是与 webpack 最大的区别。

换个角度想,如果 webpack 和 babel 都是干同一份工作,那两者就不可能一起运作,属矛盾关系。

4.2 Webpack 文档资料过于庞大,有必要全阅读完?

这是完全没必要的,每个人的工作性质都不一样,用到哪看到哪儿即可,过不了多久还是会忘记。

4.3 Webpack 是不是过时了?

Webpack 从配置概念上看并不过时,它就像构建工具们的老师,可以从中学到许多东西。


完!

相关推荐
blaizeer40 分钟前
深入理解 CSS 浮动(Float):详尽指南
前端·css
小白求学11 小时前
CSS浮动
前端·css·css3
YUELEI1182 小时前
TypeScript 封装 Axios 1.7.7
typescript·axios
zifer3 小时前
在 Webpack 中使用 TypeScript语言 编写配置文件的完整指南
webpack
柏箱4 小时前
使用JavaScript写一个网页端的四则运算器
前端·javascript·css
bobostudio19957 小时前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式
Fan_web13 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常13 小时前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
赛男丨木子丿小喵13 小时前
visual studio2022添加新项中没有html和css
css·html·visual studio
Tiffany_Ho15 小时前
【TypeScript】知识点梳理(三)
前端·typescript