Node.js 模块化与 Webpack 工程化入门实践:从 CommonJS 到打包配置详解
对于前端开发者来说,Node.js 已经不仅是服务端语言,更是工程化工具的基石。本文从 Node.js 内置模块入手,贯通模块化标准、npm 包管理,最终落地到 Webpack 打包配置,帮助初学者建立完整的知识链路。## 1. Node.js 基础:文件操作与路径安全
Node.js 基于 Chrome V8 引擎,让 JavaScript 脱离浏览器运行。执行脚本只需在终端运行 `node 文件名.js`。
### fs 模块:读写文件
`fs` 是 Node.js 内置的文件系统模块。写入文件使用 `fs.writeFile(path, data, callback)`,读取文件使用 `fs.readFile(path, callback)`,读取到的 `data` 是 Buffer 对象,需调用 `.toString()` 转换为字符串。
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
});
### path 模块:解决相对路径陷阱
Node.js 中相对路径是相对于终端工作目录,而非脚本文件所在目录。不同位置执行脚本可能导致路径找不到。安全做法是使用 `__dirname`(当前文件所在目录的绝对路径)配合 `path.join()` 拼接路径。
const fs = require('fs');
const path = require('path');
const filePath = path.join(__dirname, '..', 'data.txt');
fs.readFile(filePath, (err, data) => {
if (err) console.log(err);
else console.log(data.toString());
});
`path.join()` 会自动根据操作系统规则拼接路径片段。
### 实战:压缩 HTML 文件
前端工程化中常见的一步是压缩 HTML,去除回车和换行符。
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压缩成功!');
});
});
### http 模块:搭建简易 Web 服务
使用内置 `http` 模块创建服务器,监听端口并返回响应。
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 启动');
});
根据请求路径返回不同文件(如 HTML):
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. 模块化开发:CommonJS 与 ES Modules
Node.js 中每个 `.js` 文件都是一个独立模块,变量作用域隔离。模块化带来代码复用、按需加载、便于协作。
### CommonJS 标准(Node.js 默认)
导出使用 `module.exports`,导入使用 `require()`。
// utils.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
const utils = require('./utils.js');
console.log(utils.url); // http://api.example.com
console.log(utils.sum()); // 6
内置模块直接写名字(如 `require('fs')`),自定义模块写路径(如 `require('./utils.js')`)。
### ES Modules(ECMAScript 标准)
在 `package.json` 中设置 `"type": "module"` 即可启用 ESM 语法。
**默认导出/导入**:
// utils.js
const baseUrl = 'http://api.example.com';
export default { url: baseUrl };
// index.js
import utils from './utils.js';
console.log(utils.url);
**命名导出/导入**(按需加载):
// 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());
选择策略:全部加载用默认导出,按需加载用命名导出。
## 3. npm 包管理
包(Package)是包含 `package.json` 的文件夹,分为项目包和软件包。`package.json` 记录名称、版本、入口文件(`main` 字段)。
常用命令:
- `npm init -y`:快速生成 `package.json`
- `npm i <包名>`:安装本地依赖,记录到 `dependencies`
- `npm i <包名> -g`:全局安装(如 `nodemon`)
- `npm i`:根据 `package.json` 安装所有依赖
**nodemon 全局包**:监听文件变化自动重启应用,替代 `node` 命令。使用 `nodemon app.js` 启动。
## 4. Webpack 模块打包工具
Webpack 从入口出发构建依赖图,将 JS、CSS、图片等打包成静态资源。核心能力:转译、压缩、整合。
### 基础使用
初始化项目并安装:
npm init -y
npm i webpack webpack-cli --save-dev
在 `package.json` 的 `scripts` 中添加命令:
"scripts": {
"build": "webpack"
}
运行 `npm run build`,默认入口为 `src/index.js`,输出到 `dist/main.js`。
### 核心配置文件 webpack.config.js
通过配置文件自定义打包行为。
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 打包模式:development 或 production
mode: 'development',
// 入口
entry: path.resolve(__dirname, 'src/login/index.js'),
// 出口
output: {
path: path.resolve(__dirname, 'dist'),
filename: './login/index.js'
},
// 插件
plugins: [
new HtmlWebpackPlugin({
template: './public/login.html',
filename: './login/index.html'
})
],
// 加载器
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'] // 从右向左执行
},
{
test: /\.less$/i,
use: ['style-loader', 'css-loader', 'less-loader']
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
type: 'asset',
generator: {
filename: 'assets/'
}
}
]
},
// 路径别名
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
},
// 开发服务器
devServer: {
port: 8080,
open: true,
hot: true
}
};
常用加载器说明:
- `css-loader`:解析 `@import` 和 `url()`
- `style-loader`:将 CSS 插入 DOM 的 `<style>` 标签
- `less-loader`:将 Less 编译为 CSS
安装命令:
npm i html-webpack-plugin css-loader style-loader less less-loader mini-css-extract-plugin css-minimizer-webpack-plugin --save-dev
### 常用优化配置
- **提取 CSS 为独立文件**:用 `mini-css-extract-plugin` 替代 `style-loader`,利于浏览器缓存
- **压缩 CSS**:使用 `css-minimizer-webpack-plugin`
- **Source Map**:设置 `devtool: 'inline-source-map'` 精确定位源码错误
- **CDN 排除**:通过 `externals` 配置将某些库排除打包,在 HTML 中引入 CDN 链接
- **代码分割**:在 `optimization.splitChunks` 中配置公共代码提取
### 打包模式与环境变量
`mode` 决定内置优化:`development` 启用调试和热更新,`production` 自动压缩。命令行可覆盖:`webpack --mode=production`。
通过 `cross-env` 注入环境变量:
npm i cross-env --save-dev
修改 `package.json`:
"scripts": {
"build": "cross-env NODE_ENV=production webpack",
"dev": "cross-env NODE_ENV=development webpack serve"
}
在 `webpack.config.js` 中通过 `process.env.NODE_ENV` 判断环境,用 `DefinePlugin` 将变量注入前端代码。
多页面打包只需配置多个 `entry` 和对应的 `HtmlWebpackPlugin` 实例。
## 总结
从 Node.js 文件操作、路径安全,到模块化标准、npm 包管理,再到 Webpack 全配置,本文覆盖了从前端工程化入门所需的核心知识点。掌握这些,你就能自主搭建项目构建流程,实现模块化开发和优化。
Re: Node.js 模块化与 Webpack 工程化入门实践:从 CommonJS 到打包配置详解
这篇入门文章写得非常清晰实用,把 Node.js 内置模块、模块化标准和工程化实践串成了一条完整的学习线。特别是对 `__dirname` 和 `path.join()` 的强调,确实能帮新手避开常见的路径陷阱。压缩 HTML 和搭建简易 Web 服务的例子也很有实战感,看完就能立刻上手尝试。不过标题里提到了 Webpack 打包配置,正文好像只讲到模块化部分就结束了,是后面还有内容没贴完吗?期待 Webpack 的工程化部分也能这样一步步拆解出来,对新手会更有帮助。Re: Node.js 模块化与 Webpack 工程化入门实践:从 CommonJS 到打包配置详解
楼主写得很详细,从 Node.js 基础的文件操作和路径安全讲起,层层递进到模块化开发,示例代码也很实用,特别是 `__dirname` 配合 `path.join` 解决路径陷阱那段,对新手很友好。期待后续 Webpack 打包配置的部分,希望能继续看到完整的工程化流程讲解。Re: Node.js 模块化与 Webpack 工程化入门实践:从 CommonJS 到打包配置详解
楼主写得非常清晰,从 Node.js 内置模块到模块化标准再到 Webpack 配置,这条链路对初学者来说确实很有帮助。特别是 `path.join` 和 `__dirname` 那部分,以前我经常因为工作目录不同而报错,看了这个终于明白为什么推荐用绝对路径拼接了。另外那个压缩 HTML 的小例子也很实用,直接就能用上。期待后面的 ES Modules 和 Webpack 配置部分,楼主能继续更新吗?
页:
[1]