第11课:小白进阶必看!JavaScript 模块化与工程化—从脚本到项目

不为模糊不清的未来担忧,只为清清楚楚的现在奋斗!

当你面对数千行代码混杂的 HTML、全局变量冲突、手动刷新页面的开发方式时,是否渴望拥有现代前端工程化的能力?本节课将带你完成从“草台班子”到“正规军”的蜕变,用 Webpack+Babel 武装项目,最后将天气工具工程化部署!

一、模块化:代码组织的革命

  1. 为什么需要模块化?

传统开发痛点

  • 全局变量污染:script.js 中 var data = … 被意外覆盖

  • 依赖混乱:手动维护 JS 加载顺序

  • 协作困难:多人修改同一文件冲突频发

模块化解决方案

  • 高内聚低耦合:每个模块独立功能,通过接口通信

  • 依赖管理:自动解析模块间依赖关系

  • 命名空间隔离:避免全局污染

2. 模块化规范演进

规范环境特性示例
IIFE浏览器立即执行函数隔离作用域(function(){ … })()
CommonJSNode.jsrequire/module.exports 同步加载module.exports = {}
ES Modules浏览器/Node官方标准,import/export 静态分析export const api = …

ES Modules 核心语法

// utils.js
export const formatDate = (date) => { /* ... */ };
export default function http(url) { /* ... */ }

// app.js
import http, { formatDate } from './utils.js';

二、工程化:前端开发的工业革命

1. 为什么需要工程化?

开发阶段: 代码压缩、Sass/Less 预处理、语法校验

协作阶段 : 统 一代码风格、静态类型检查

部署阶段: 文件指纹、CDN 托管、按需加载

2. 现代工程化工具链

工具角色核心能力
Webpack打包工程师模块打包、代码分割、加载器
Babel语言翻译官ES6+转 ES5、Polyfill
ESLint代码质检员语法检查、风格统一
npm后勤部长依赖管理、脚本执行

三、Webpack 核心配置详解

1. 基础配置(webpack.config.js)

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/index.js',      // 入口文件
    output: {                     // 输出配置
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.[hash:8].js'
    },
    module: {                    // 加载器配置
        rules: [
            {
                test: /\.js$/,         // 匹配JS文件
                use: 'babel-loader',    // 使用Babel转译
                exclude: /node_modules/
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']  // 从右到左执行
            }
        ]
    },
    plugins: [                   // 插件配置
        new HtmlWebpackPlugin(
            {
                template: './src/view/index.html'
            }
        )
    ]
};

2. 开发效率优化

// package.json
{
  "scripts": {
    "start": "webpack serve --mode development", // 启动开发服务器
    "build": "webpack --mode production"        // 生产构建
  }
}

四、实战:天气工具工程化改造

weather/
├── src/
│   ├── index.js          # 入口文件
│   ├── api/              # 网络请求模块
│   ├── utils/            # 工具函数
├── ├── view/             # DOM操作模块
│   └── assets/           # 静态资源
├── public/               # 公共文件
│   └── index.html        # 当前文件
├── webpack.config.js     # Webpack配置
└── package.json          # 依赖文件

2. 模块化拆分

// src/api/weather.js
export async function getWeather(city) {
    const response = await fetch(`https://devapi.qweather.com/v7/weather/now?location=${city}&key=772e2fb170e64febb119c74c71d65fd1`);
    return response.json();
}

// src/utils/dom.js
export function showError(message) {
    const errorEl = document.getElementById('error');
    errorEl.textContent = `${message}`;
    errorEl.classList.remove('hidden');
}
export function createElement(tagName, classNames) {
    const element = document.createElement(tagName);
    if (classNames) {
        element.classList.add(...classNames);
    }
    return element;
}
export function displayWeather(data) {
    const container = document.getElementById('weatherResult');
    if (!container) {
        console.error('Container with id "weatherResult" not found!');
        return;
    }
    const { icon, temp, text, windDir, humidity, pressure } = data;

    const card = createElement('div', ['weather-card']);
    card.innerHTML = `
      <i class="qi-${icon}"></i>
      <p>温度:${temp}℃</p>
      <p>天气:${text}</p>
      <p>风向:${windDir}</p>
      <p>湿度:${humidity}%</p>
      <p>气压:${pressure} hPa</p>
    `;
    container.appendChild(card);
}

// src/index.js
// 将功能挂载到全局(实际项目建议用模块化方式)
import { getWeather } from './api/weather';
import { displayWeather, showError } from './utils/dom';

window.handleSearch = async () => {
    const cityInput = document.getElementById('cityInput');
    try {
        const data = await getWeather(cityInput.value);
        displayWeather(data.now);
    } catch (error) {
        showError(error.message);
    }
}

3.index 主页面

<body>
    <div class="container">
        <!-- 查询区域 -->
        <div class="search-box">
            <input type="text" id="cityInput" placeholder="输入城市名称,如:北京" class="search-input">
            <button onclick="window.handleSearch()" class="search-btn">
                查询天气
            </button>
        </div>
        <!-- 结果显示区域 -->
        <div id="weatherResult" class="result-container">
            <!-- 初始状态提示 -->
            <div class="placeholder">输入城市名称查看实时天气 🌞</div>
        </div>
        <!-- 错误提示 (通过JS动态插入) -->
        <div id="error" class="error-container hidden"></div>
    </div>
</body>

4. 添加构建命令(需要安装 node)

# 安装依赖
npm install webpack webpack-cli webpack-dev-server babel-loader @babel/core @babel/preset-env html-webpack-plugin --save-dev

# 启动开发服务器
npm run start

# 生产环境打包(打包成dist)
npm run build


源码后台【回复:JS】

下节预告

第 12 课:小白进阶必看!客户端数据存储

  • localStorage 与 sessionStorage
  • Cookie 基础操作

回复【JS】获取本课源码+工具包!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值