【Node.js 】Node.js 与 Webpack 模块化工程化入门指南

文章目录

    • [1. Node.js入门基础](#1. Node.js入门基础)
      • [1.1 什么是 Node.js?](#1.1 什么是 Node.js?)
      • [1.2 fs 模块 - 读写文件](#1.2 fs 模块 - 读写文件)
      • [1.3 path 模块 - 处理路径](#1.3 path 模块 - 处理路径)
      • [1.4 简易前端工程化实践:压缩 HTML](#1.4 简易前端工程化实践:压缩 HTML)
      • [1.5 Web 服务基础](#1.5 Web 服务基础)
        • [使用 http 模块创建 Web 服务](#使用 http 模块创建 Web 服务)
        • 返回网页资源
    • [2. 模块化开发](#2. 模块化开发)
      • [2.1 模块化简介](#2.1 模块化简介)
      • [2.2 CommonJS 标准(Node.js 默认)](#2.2 CommonJS 标准(Node.js 默认))
      • [2.3 ECMAScript 标准 (ES Modules)](#2.3 ECMAScript 标准 (ES Modules))
    • [3. npm 与包管理](#3. npm 与包管理)
      • [3.1 包 (Package) 的概念](#3.1 包 (Package) 的概念)
      • [3.2 npm (Node Package Manager)](#3.2 npm (Node Package Manager))
    • [4. Webpack 模块打包工具](#4. Webpack 模块打包工具)
      • [4.1 Webpack 简介](#4.1 Webpack 简介)
      • [4.2 核心配置 (`webpack.config.js`)](#4.2 核心配置 (webpack.config.js))
      • [4.3 常用优化](#4.3 常用优化)
      • [4.4 打包模式与环境变量](#4.4 打包模式与环境变量)
    • [5. 常用开发环境配置与优化](#5. 常用开发环境配置与优化)

1. Node.js入门基础

1.1 什么是 Node.js?

Node.js 是一个基于 Chrome V8 引擎的独立 JavaScript 运行环境。它使得 JavaScript 可以脱离浏览器运行,主要用于:

  • 编写服务器端程序:构建后端API、Web服务。
  • 前端工程化:对前端代码进行压缩、转译、整合等,提高开发效率。

与浏览器环境的区别 :Node.js 环境中没有 浏览器提供的 documentwindow 等 BOM/DOM 对象,但完全支持 ECMAScript 标准语法。

如何执行代码

  1. 在终端中切换到脚本所在目录。
  2. 执行命令:node 你的文件名.js

示例 (hello.js):

js 复制代码
console.log('Hello, Node.js!');
for (let i = 0; i < 3; i++) {
  console.log(i);
}

在终端执行:node hello.js

1.2 fs 模块 - 读写文件

fs 是 Node.js 内置的模块,用于与文件系统交互。

  • 导入模块const fs = require('fs')
  • 写入文件fs.writeFile(文件路径, 写入内容, 回调函数)
  • 读取文件fs.readFile(文件路径, 回调函数)。读取到的 data 是一个 Buffer 数据流,需要用 .toString() 方法转换。
js 复制代码
const fs = require('fs');

// 写入文件
fs.writeFile('./test.txt', 'Hello FS', (err) => {
  if (err) console.log(err);
  else console.log('写入成功');
});

// 读取文件
fs.readFile('./test.txt', (err, data) => {
  if (err) console.log(err);
  else console.log(data.toString()); // 输出: Hello FS
});

1.3 path 模块 - 处理路径

在 Node.js 执行代码时,相对路径的参照点是终端所在的工作目录 ,而不是代码文件所在目录。这可能导致在不同位置运行脚本时路径解析错误。建议始终使用绝对路径。

使用 __dirname (当前文件所在文件夹的绝对路径)配合 path.join() 方法来构建安全的绝对路径。

js 复制代码
const fs = require('fs');
const path = require('path');

// ❌ 危险:相对路径依赖终端位置
// fs.readFile('../data.txt', ...)

// ✅ 安全:使用绝对路径
const filePath = path.join(__dirname, '..', 'data.txt');
console.log(filePath); // 输出类似: /Users/xxx/project/data.txt
fs.readFile(filePath, (err, data) => {
  // ...
});

path.join() 的作用:根据所在操作系统的规则,正确地将多个路径片段拼接成一个完整的路径。

1.4 简易前端工程化实践:压缩 HTML

前端工程化 是使用工具对前端代码进行压缩、转译、整合、自动化部署等一系列操作,以提高开发效率和质量。

需求 :将 HTML 文件中的回车符 (\r) 和换行符 (\n) 移除,实现代码压缩。

js 复制代码
const fs = require('fs');
const path = require('path');

fs.readFile(path.join(__dirname, 'public', 'index.html'), (err, data) => {
  const htmlStr = data.toString();
  // 使用正则表达式全局替换所有回车和换行符
  const resultStr = htmlStr.replace(/[\r\n]/g, '');
  fs.writeFile(path.join(__dirname, 'dist', 'index.html'), resultStr, err => {
    if (err) console.log(err);
    else console.log('HTML压缩成功!');
  });
});

1.5 Web 服务基础

  • URL 端口号:用于标记服务器中不同的服务程序,范围 0-65535。HTTP 服务默认端口是 80。
  • Web 服务:一个提供网上信息浏览功能的程序。
使用 http 模块创建 Web 服务
js 复制代码
const http = require('http');

const server = http.createServer();

server.on('request', (req, res) => {
  // 设置响应头
  res.setHeader('Content-Type', 'text/plain;charset=utf-8');
  // 设置响应体,结束本次请求
  res.end('欢迎使用 Node.js 创建的 Web 服务');
});

server.listen(3000, () => {
  console.log('Web 服务已在 http://localhost:3000 启动');
});

访问:http://localhost:3000

返回网页资源

可以根据请求路径,返回不同的内容(如 HTML 文件)。

js 复制代码
server.on('request', (req, res) => {
  if (req.url === '/index.html') {
    fs.readFile(path.join(__dirname, 'dist/index.html'), (err, data) => {
      res.setHeader('Content-Type', 'text/html;charset=utf-8');
      res.end(data.toString());
    });
  } else {
    res.setHeader('Content-Type', 'text/html;charset=utf-8');
    res.end('404 页面不存在');
  }
});

2. 模块化开发

2.1 模块化简介

在 Node.js 中,每个 .js 文件都被视为一个独立的模块 。模块内部定义的变量、函数拥有独立作用域,不会污染全局。

模块化的好处:代码复用、按需加载、独立作用域、便于协作。

2.2 CommonJS 标准(Node.js 默认)

  • 导出模块module.exports = { ... }
  • 导入模块const 变量 = require('模块标识')
    • 内置模块:直接写名字,如 require('fs')
    • 自定义模块:写文件路径,如 require('./utils.js')

示例 (utils.js):

js 复制代码
const baseUrl = 'http://api.example.com';
const sumArray = arr => arr.reduce((s, v) => s + v, 0);

module.exports = {
  url: baseUrl,
  sum: sumArray
};

示例 (index.js):

js 复制代码
const utils = require('./utils.js');
console.log(utils.url); // 'http://api.example.com'
console.log(utils.sum([1,2,3])); // 6

2.3 ECMAScript 标准 (ES Modules)

在项目中新建 package.json 并设置 { "type": "module" } 后,即可使用 ES6 模块语法。

  • 默认导出与导入

    js 复制代码
    // utils.js (导出)
    const baseUrl = 'http://api.example.com';
    export default { url: baseUrl };
    
    // index.js (导入)
    import utils from './utils.js';
    console.log(utils.url);
  • 命名导出与导入 (按需加载)

    js 复制代码
    // utils.js (导出)
    export const baseUrl = 'http://api.example.com';
    export const sumArray = arr => arr.reduce((s, v) => s + v, 0);
    
    // index.js (导入)
    import { baseUrl, sumArray } from './utils.js';
    console.log(baseUrl, sumArray([1,2,3]));

如何选择:全部加载用默认导出,按需加载用命名导出。


3. npm 与包管理

3.1 包 (Package) 的概念

将模块、代码、资源等聚合成的一个文件夹,称为"包"。

  • 项目包:编写业务逻辑的代码。
  • 软件包:封装了工具和方法供开发者使用。
  • 核心 :包的根目录必须有 package.json 文件,记录包的名称、版本、入口文件等信息。
  • 导入require('包名/路径') 时,默认导入的是包内 package.jsonmain 字段指定的文件,或 index.js 文件。

3.2 npm (Node Package Manager)

npm 是 Node.js 环境的软件包管理器,用于下载和管理项目依赖。

基础命令

  1. 初始化项目清单npm init -y (快速生成 package.json)
  2. 安装本地软件包npm i 包名 (安装到当前项目的 node_modules 下,并记录在 package.jsondependencies 中)
    • 示例:npm i axios
  3. 安装全局软件包npm i 包名 -g (安装到系统全局,通常用于工具命令)
    • 示例:npm i nodemon -g
  4. 根据 package.json 安装所有依赖npm i (在拿到新项目且无 node_modules 文件夹时使用)
  5. 清屏 (终端内):cls (Windows) 或 clear (Mac/Linux) 或 Ctrl + L

全局包示例:nodemon

  • 作用 :替代 node 命令,监听代码变化并自动重启应用,提高开发效率。
  • 使用 :安装后,用 nodemon app.js 替代 node app.js 启动应用。

4. Webpack 模块打包工具

4.1 Webpack 简介

Webpack 是一个静态模块打包工具。它会从一个或多个入口点出发,构建一个依赖关系图,将所有模块(JS、CSS、图片、字体等)打包成一个或多个用于生产环境使用的静态资源包。

核心作用:实现前端工程化,例如将 Less/Sass 转成 CSS、将 ES6+ 语法降级、压缩代码、整合资源等。

基础使用

  1. 初始化项目并安装 Webpack:

    bash 复制代码
    npm init -y
    npm i webpack webpack-cli --save-dev
  2. package.jsonscripts 中配置自定义命令:

    json 复制代码
    "scripts": {
      "build": "webpack"
    }
  3. 运行 npm run build 进行打包。默认入口是 src/index.js,默认输出到 dist/main.js

4.2 核心配置 (webpack.config.js)

Webpack 的行为通过配置文件进行修改。以下是关键配置项:

js 复制代码
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // 1. 打包模式:'development' | 'production'
  mode: 'development',

  // 2. 入口 (可配置多入口)
  entry: path.resolve(__dirname, 'src/login/index.js'),

  // 3. 出口
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: './login/index.js'
  },

  // 4. 插件 (扩展功能)
  plugins: [
    // 自动生成HTML文件并引入打包后的JS
    new HtmlWebpackPlugin({
      template: './public/login.html', // 模板
      filename: './login/index.html'    // 输出位置
    })
  ],

  // 5. 加载器 (让Webpack能处理非JS资源)
  module: {
    rules: [
      // 处理 CSS
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'] // 从右向左执行
      },
      // 处理 Less
      {
        test: /\.less$/i,
        use: ['style-loader', 'css-loader', 'less-loader']
      },
      // 处理图片资源
      {
        test: /\.(png|jpg|jpeg|gif)$/i,
        type: 'asset',
        generator: {
          filename: 'assets/[hash][ext]' // 输出文件名格式
        }
      }
    ]
  },

  // 6. 解析配置
  resolve: {
    alias: { // 路径别名
      '@': path.resolve(__dirname, 'src')
    }
  },

  // 7. 开发服务器
  devServer: {
    port: 8080,
    open: true, // 自动打开浏览器
    hot: true   // 热模块替换
  }
};

常用插件和加载器安装:

bash 复制代码
npm i html-webpack-plugin css-loader style-loader less less-loader mini-css-extract-plugin css-minimizer-webpack-plugin --save-dev

常用加载器说明

  • css-loader:解析 @importurl() 语法。
  • style-loader:将解析后的 CSS 通过 <style> 标签插入到 DOM。
  • less-loader:将 Less 编译为 CSS。

4.3 常用优化

  • 提取 CSS 为独立文件 :使用 mini-css-extract-plugin 插件替代 style-loader,方便浏览器缓存。
  • 压缩 CSS :使用 css-minimizer-webpack-plugin 插件。
  • 设置路径别名 :在 resolve.alias 中配置,简化导入路径(如用 @ 代表 src 目录)。
  • 开发环境调错 (Source Map) :配置 devtool: 'inline-source-map',可在浏览器中精确定位源代码错误位置。
  • 生产环境使用 CDN :通过配置 externals 排除某些库不打入包,并在 HTML 模板中通过条件判断引入 CDN 链接,以减小打包体积。
  • 分割公共代码 :在 optimization.splitChunks 中配置,将多个页面/入口共用的模块提取成单独文件。

4.4 打包模式与环境变量

  • 模式 (Mode)
    • development:启用调试、热更新等功能。
    • production:自动压缩代码、优化资源。
    • 可通过命令行 --mode=production 设置,优先级高于配置文件。
  • 区分环境
    1. 安装 cross-envnpm i cross-env --save-dev

    2. 修改 package.json 命令,注入环境变量:

      json 复制代码
      "scripts": {
        "build": "cross-env NODE_ENV=production webpack",
        "dev": "cross-env NODE_ENV=development webpack serve"
      }
    3. webpack.config.js 中通过 process.env.NODE_ENV 判断环境。

    4. 通过 DefinePlugin 将环境变量注入到前端代码中。

  • 多页面打包 :配置多个 entry 和对应的 HtmlWebpackPlugin 实例即可。

5. 常用开发环境配置与优化

  1. 开发服务器 :使用 webpack-dev-server 提供实时重新加载和热模块替换功能。
  2. 环境变量注入 :使用 DefinePlugin 将 Node.js 环境中的变量注入到前端代码中。
  3. 路径解析 :通过 resolve.alias 配置别名,简化导入语句。
  4. 生产优化:结合 CDN、代码分割、公共代码提取等手段优化产物体积和加载性能。

通过以上学习,你可以掌握从 Node.js 基础、模块化开发、npm 包管理,到使用 Webpack 进行现代化前端项目构建和优化的完整知识链路。

相关推荐
爱学习的程序媛2 小时前
【Web前端】“十五五”重大项目中的前端机遇
前端·科技·信息可视化·前端框架·创业创新·信息与通信
始持2 小时前
第十二讲 风格与主题统一
前端·flutter
小码哥_常2 小时前
Room 3.0大变身:安卓开发的新挑战与机遇
前端
法欧特斯卡雷特2 小时前
Kotlin 2.3.20 现已发布,来看看!
android·前端·后端
Wect2 小时前
LeetCode 53. 最大子数组和:两种高效解法(动态规划+分治)
前端·算法·typescript
始持2 小时前
第十三讲 异步操作与异步构建
前端·flutter
读忆2 小时前
解决 `:first-child` / `:last-child` 不生效的问题
前端·css·vue.js·css3
兔年鸿运Q小Q2 小时前
vue 使用public数据
前端·javascript·vue.js
wuhen_n2 小时前
开发环境优化完全指南:告别等待,让开发如丝般顺滑
前端·javascript·vue.js