阅读视图

发现新文章,点击刷新页面。

现代 JavaScript 特性:TypeScript 深度解析与实践

引言

TypeScript作为JavaScript的超集,为现代前端开发带来了强大的类型系统和面向对象编程能力。它不仅在编译时提供类型检查,还支持ECMAScript的最新特性,极大地提高了代码的可维护性和开发体验。本文将深入探讨TypeScript的核心特性,包括类型检查、接口泛型、装饰器等底层实现原理,并补充类型推断、高级类型、工程化实践等关键内容,通过完整代码示例展示TypeScript在真实项目中的应用价值。

一、类型检查的简单实现

运行时类型检查的基础

TypeScript在编译时进行类型检查,但理解其背后的原理有助于我们实现运行时类型检查。

// 1.1 基础类型检查器
class TypeChecker {
  static isString(value) {
    return typeof value === "string";
  }

  static isNumber(value) {
    return typeof value === "number" && !isNaN(value);
  }

  static isBoolean(value) {
    return typeof value === "boolean";
  }

  static isArray(value) {
    return Array.isArray(value);
  }

  static isObject(value) {
    return value !== null && typeof value === "object" && !Array.isArray(value);
  }

  static isFunction(value) {
    return typeof value === "function";
  }

  static isNull(value) {
    return value === null;
  }

  static isUndefined(value) {
    return typeof value === "undefined";
  }

  // 复合类型检查
  static isType(value, expectedType) {
    switch (expectedType) {
      case "string":
        return this.isString(value);
      case "number":
        return this.isNumber(value);
      case "boolean":
        return this.isBoolean(value);
      case "array":
        return this.isArray(value);
      case "object":
        return this.isObject(value);
      case "function":
        return this.isFunction(value);
      case "null":
        return this.isNull(value);
      case "undefined":
        return this.isUndefined(value);
      default:
        throw new Error(`Unsupported type: ${expectedType}`);
    }
  }
}

console.log(TypeChecker.isString("hello")); // true
console.log(TypeChecker.isNumber(42)); // true
console.log(TypeChecker.isType([1, 2, 3], "array")); // true

// 1.2 增强的类型检查器
class EnhancedTypeChecked {
  static types = {
    string: (value) => typeof value === "string",
    number: (value) => typeof value === "number" && !isNaN(value),
    boolean: (value) => typeof value === "boolean",
    array: (value) => Array.isArray(value),
    object: (value) =>
      value !== null && typeof value === "object" && !Array.isArray(value),
    function: (value) => typeof value === "function",
    null: (value) => value === null,
    undefined: (value) => typeof value === "undefined",
    // 自定义类型
    email: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value),
    uuid: (value) =>
      /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
        value
      ),
    date: (value) => value instanceof Date,
    // 联合类型
    union: (value, types) => types.some((type) => this.check(value, type)),
    // 字面量类型
    literal: (value, expected) => vaue === expected,
  };

  static check(value, type) {
    if (typeof type === "string") {
      const checker = this.types[type];
      return checker ? checker(value) : false;
    }
    if (typeof type === "object" && type.type) {
      if (type.type === "union") {
        return this.types.union(value, type.types);
      }
      if (type.type === "literal") {
        return this.types.literal(value, type.value);
      }
    }

    return false;
  }

  static validate(value, schema) {
    if (typeof schema === "string") {
      return this.check(value, schema);
    }

    if (Array.isArray(schema)) {
      // 数组类型
      if (!this.check(value, "array")) {
        return false;
      }
      const [itemType] = schema;
      return value.every((item) => this.validate(item, itemType));
    }

    if (typeof schema === "object" && !Array.isArray(schema)) {
      // 对象类型
      if (!this.check(value, "object")) return false;

      for (const [key, propSchema] of Object.entries(schema)) {
        if (!this.validate(value[key], propSchema)) {
          return false;
        }
      }

      return true;
    }
    return false;
  }
}

// 使用示例
const schema = {
  name: "string",
  age: "number",
  email: "email",
  tags: ["string"],
  address: {
    street: "string",
    city: "string",
  },
};

const data = {
  name: "John",
  age: 30,
  email: "john@example.com",
  tags: ["developer", "typescript"],
  address: {
    street: "123 Main St",
    city: "New York",
  },
};

console.log(EnhancedTypeChecked.validate(data, schema)); // true

// 1.3 编译时类型检查模拟
function createTypeSafeProxy(target, schema) {
  return new Proxy(target, {
    set(obj, prop, value) {
      if (schema[prop]) {
        const isValid = EnhancedTypeChecked.validate(value, schema[prop]);
        if (!isValid) {
          throw new TypeError(
            `Invalid type for property ${prop}. Expected ${JSON.stringify(
              schema[prop]
            )}, got ${typeof value}`
          );
        }
      }
      obj[prop] = value;
      return true;
    },
    get(obj, prop) {
      return obj[prop];
    },
  });
}

const userSchema = {
  name: "string",
  age: "number",
  active: "boolean",
};

const user = createTypeSafeProxy({}, userSchema);

try {
  user.name = "Alice"; // 成功
  user.age = "25"; // Invalid type for property age. Expected "number", got string
} catch (error) {
  console.error(error.message);
}
TypeScript编译器模拟
class SimpleTypeScriptCompiler {
  constructor() {
    this.typeRegistry = new Map();
    this.errors = [];
  }

  // 解析类型注释
  parseTypeAnnotation(code) {
    const typeRegex = /:\s*([^{}\[\]]+|\{[^}]+\}|\[[^\]]+\])/g;
    const matches = [];
    let match;

    while ((match = typeRegex.exec(code)) !== null) {
      matches.push(match[1].trim());
    }

    return matches;
  }

  // 提取接口定义
  extractInterface(code) {
    const interfaceRegex = /interface\s+(\w+)\s*\{([^}]+)\}/g;
    const interfaces = new Map();
    let match;

    while ((match = interfaceRegex.exec(code)) !== null) {
      const [, name, body] = match;
      const properties = {};

      body.split(";").forEach((line) => {
        const propMatch = line.trim().match(/(\w+)\s*:\s*([^;]+)/);
        if (propMatch) {
          const [, propName, propType] = propMatch;
          properties[propName] = propType.trim();
        }
      });

      interfaces.set(name, properties);
    }

    return interfaces;
  }

  // 检查函数类型
  checkFunctionTypes(code, interfaces) {
    const functionRegex =
      /function\s+(\w+)\(([^)]*)\)\s*(?::\s*([^{]+))?\s*\{/g;
    const errors = [];
    let match;

    while ((match = functionRegex.exec(code)) !== null) {
      const [, functionName, params, returnType] = match;

      // 检查参数类型
      if (params) {
        params.split(",").forEach((param) => {
          const paramMatch = param.match(/(\w+)\s*:\s*(\w+)/);
          if (paramMatch) {
            const [, paramName, paramType] = paramMatch;
            // 这里可以添加实际类型检查逻辑
          }
        });
      }

      // 这里可以添加返回值类型检查逻辑
    }

    return errors;
  }

  // 编译TypeScript代码
  compile(code) {
    this.errors = [];

    // 提取接口
    const interfaces = this.extractInterface(code);

    // 检查类型
    const typeErrors = this.checkFunctionTypes(code, interfaces);
    this.errors.push(...typeErrors);

    // 移除类型注释, 生成JavaScript代码
    let jsCode = code
      .replace(/:\s*([^{}\[\]]+|\{[^}]+\}|\[[^\]]+\])/g, "") // 移除参数和变量类型
      .replace(/interface\s+\w+\s*\{[^}]+\}/g, "") // 移除接口定义
      .replace(/\s*\/\/.*$/gm, "") // 移除注释
      .trim();

    return {
      jsCode,
      errors: this.errors,
      interfaces: Array.from(interfaces.entries()),
    };
  }
}

// 使用示例
const tsCode = `
interface User {
  name: string;
  age: number;
}

function greet(user: User): string {
  return "Hello, " + user.name;
}

const john: User = { name: "John", age: 30 };
console.log(greet(john));
`;

const compiler = new SimpleTypeScriptCompiler();
const result = compiler.compile(tsCode);

console.log("生成的JavaScript代码:");
console.log(result.jsCode);
console.log("提取的接口:", result.interfaces);
console.log("类型错误:", result.errors);

二、接口和泛型的模拟

接口的实现与模拟
// 2.1 接口检查器
class InterfaceChecker {
  static interfaces = new Map();
  
  // 定义接口
  static defineInterface(name, structure) {
    this.interfaces.set(name, structure);
  }
  
  // 检查对象是否实现接口
  static implements(obj, interfaceName) {
    const interfaceDef = this.interfaces.get(interfaceName);
    if (!interfaceDef) {
      throw new Error(`接口 ${interfaceName} 未定义`);
    }
    
    // 检查所有必需属性
    for (const [prop, type] of Object.entries(interfaceDef.required || {})) {
      if (!(prop in obj)) {
        return false;
      }
      if (type && !this.checkType(obj[prop], type)) {
        return false;
      }
    }
    
    // 检查可选属性类型(如果存在)
    for (const [prop, type] of Object.entries(interfaceDef.optional || {})) {
      if (prop in obj && type && !this.checkType(obj[prop], type)) {
        return false;
      }
    }
    
    // 检查方法
    for (const method of interfaceDef.methods || []) {
      if (!(method in obj) || typeof obj[method] !== 'function') {
        return false;
      }
    }
    
    return true;
  }
  
  // 类型检查
  static checkType(value, type) {
    if (typeof type === 'string') {
      switch (type) {
        case 'string': return typeof value === 'string';
        case 'number': return typeof value === 'number' && !isNaN(value);
        case 'boolean': return typeof value === 'boolean';
        case 'object': return value !== null && typeof value === 'object';
        default: return true;
      }
    }
    
    if (Array.isArray(type)) {
      return Array.isArray(value) && value.every(item => this.checkType(item, type[0]));
    }
    
    return true;
  }
  
  // 创建实现接口的类
  static createClass(interfaceName, implementation) {
    const interfaceDef = this.interfaces.get(interfaceName);
    if (!interfaceDef) {
      throw new Error(`接口 ${interfaceName} 未定义`);
    }
    
    // 创建类
    const DynamicClass = class {
      constructor(...args) {
        if (implementation.constructor) {
          implementation.constructor.apply(this, args);
        }
        
        // 验证实例是否符合接口
        if (!this.implements(interfaceName)) {
          throw new Error(`类未正确实现接口 ${interfaceName}`);
        }
      }
      
      implements(interfaceName) {
        return InterfaceChecker.implements(this, interfaceName);
      }
    };
    
    // 添加接口要求的方法和属性
    for (const [prop, descriptor] of Object.entries(implementation)) {
      if (prop !== 'constructor') {
        Object.defineProperty(DynamicClass.prototype, prop, descriptor);
      }
    }
    
    return DynamicClass;
  }
}

// 定义接口
InterfaceChecker.defineInterface('Serializable', {
  required: {
    toJSON: 'function',
    fromJSON: 'function'
  }
});

InterfaceChecker.defineInterface('User', {
  required: {
    id: 'number',
    name: 'string'
  },
  optional: {
    email: 'string',
    age: 'number'
  },
  methods: ['save', 'delete']
});

// 2.2 使用接口
const UserClass = InterfaceChecker.createClass('User', {
  constructor: function(id, name) {
    this.id = id;
    this.name = name;
  },
  
  save: {
    value: function() {
      console.log(`保存用户 ${this.name}`);
      return true;
    }
  },
  
  delete: {
    value: function() {
      console.log(`删除用户 ${this.name}`);
      return true;
    }
  },
  
  toJSON: {
    value: function() {
      return {
        id: this.id,
        name: this.name
      };
    }
  }
});

const user = new UserClass(1, 'Alice');
console.log(user.implements('User')); // true
console.log(user.implements('Serializable')); // false

// 2.3 运行时接口验证装饰器
function implementsInterface(interfaceName) {
  return function(target) {
    const originalConstructor = target;
    
    // 返回新的构造函数
    const newConstructor = function(...args) {
      const instance = new originalConstructor(...args);
      
      if (!InterfaceChecker.implements(instance, interfaceName)) {
        throw new Error(`类 ${target.name} 未实现接口 ${interfaceName}`);
      }
      
      return instance;
    };
    
    // 复制原型链
    newConstructor.prototype = originalConstructor.prototype;
    
    return newConstructor;
  };
}

// 使用装饰器
@interface('User')
class AdminUser {
  constructor(id, name) {
    this.id = id;
    this.name = name;
  }
  
  save() {
    console.log('保存管理员');
  }
  
  delete() {
    console.log('删除管理员');
  }
}

try {
  const admin = new AdminUser(1, 'Admin');
  console.log('AdminUser创建成功');
} catch (error) {
  console.error(error.message);
}
泛型的实现与模拟
// 2.4 泛型容器类
class GenericContainer {
  constructor(value) {
    this._value = value;
  }
  
  get value() {
    return this._value;
  }
  
  set value(newValue) {
    this._value = newValue;
  }
  
  // 泛型方法:转换值类型
  map(transformer) {
    return new GenericContainer(transformer(this._value));
  }
  
  // 检查类型(运行时)
  checkType(expectedType) {
    return typeof this._value === expectedType;
  }
}

// 使用示例
const numberContainer = new GenericContainer(42);
console.log(numberContainer.value); // 42
console.log(numberContainer.checkType('number')); // true

const stringContainer = numberContainer.map(n => `数字: ${n}`);
console.log(stringContainer.value); // "数字: 42"
console.log(stringContainer.checkType('string')); // true

// 2.5 泛型函数工厂
function createGenericFunction(typeCheck) {
  return {
    // 泛型身份函数
    identity: function(value) {
      if (typeCheck && !typeCheck(value)) {
        throw new TypeError('类型不匹配');
      }
      return value;
    },
    
    // 泛型数组操作
    filterArray: function(arr, predicate) {
      if (!Array.isArray(arr)) {
        throw new TypeError('第一个参数必须是数组');
      }
      return arr.filter(predicate);
    },
    
    // 泛型映射
    mapArray: function(arr, mapper) {
      if (!Array.isArray(arr)) {
        throw new TypeError('第一个参数必须是数组');
      }
      return arr.map(mapper);
    }
  };
}

// 创建特定类型的泛型函数
const numberFunctions = createGenericFunction(val => typeof val === 'number');
const stringFunctions = createGenericFunction(val => typeof val === 'string');

console.log(numberFunctions.identity(123)); // 123
console.log(stringFunctions.identity('hello')); // "hello"

// 2.6 泛型约束模拟
class GenericValidator {
  static validate(value, constraints) {
    // 类型约束
    if (constraints.type && typeof value !== constraints.type) {
      return false;
    }
    
    // 最小/最大值约束
    if (constraints.min !== undefined && value < constraints.min) {
      return false;
    }
    
    if (constraints.max !== undefined && value > constraints.max) {
      return false;
    }
    
    // 长度约束
    if (constraints.minLength !== undefined && value.length < constraints.minLength) {
      return false;
    }
    
    if (constraints.maxLength !== undefined && value.length > constraints.maxLength) {
      return false;
    }
    
    // 自定义验证函数
    if (constraints.validator && !constraints.validator(value)) {
      return false;
    }
    
    return true;
  }
  
  // 创建受约束的泛型类
  static createConstrainedClass(constraints) {
    return class ConstrainedContainer {
      constructor(value) {
        if (!GenericValidator.validate(value, constraints)) {
          throw new Error('值不符合约束条件');
        }
        this._value = value;
      }
      
      get value() {
        return this._value;
      }
      
      set value(newValue) {
        if (!GenericValidator.validate(newValue, constraints)) {
          throw new Error('新值不符合约束条件');
        }
        this._value = newValue;
      }
    };
  }
}

// 使用泛型约束
const NumberContainer = GenericValidator.createConstrainedClass({
  type: 'number',
  min: 0,
  max: 100
});

const StringContainer = GenericValidator.createConstrainedClass({
  type: 'string',
  minLength: 2,
  maxLength: 50
});

try {
  const numContainer = new NumberContainer(50); // 成功
  console.log(numContainer.value); // 50
  
  const strContainer = new StringContainer('Hello'); // 成功
  console.log(strContainer.value); // "Hello"
  
  // numContainer.value = 150; // 抛出错误
} catch (error) {
  console.error(error.message);
}

// 2.7 泛型工具类型模拟
class GenericUtils {
  // 模拟 Partial<T>
  static partial(obj) {
    const result = {};
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        result[key] = obj[key];
      }
    }
    return result;
  }
  
  // 模拟 Readonly<T>
  static readonly(obj) {
    const result = {};
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        Object.defineProperty(result, key, {
          value: obj[key],
          writable: false,
          enumerable: true,
          configurable: false
        });
      }
    }
    return Object.freeze(result);
  }
  
  // 模拟 Pick<T, K>
  static pick(obj, keys) {
    const result = {};
    keys.forEach(key => {
      if (key in obj) {
        result[key] = obj[key];
      }
    });
    return result;
  }
  
  // 模拟 Omit<T, K>
  static omit(obj, keys) {
    const result = {};
    for (const key in obj) {
      if (obj.hasOwnProperty(key) && !keys.includes(key)) {
        result[key] = obj[key];
      }
    }
    return result;
  }
  
  // 模拟 Record<K, T>
  static record(keys, valueCreator) {
    const result = {};
    keys.forEach(key => {
      result[key] = valueCreator(key);
    });
    return result;
  }
}

// 使用泛型工具
const user = {
  id: 1,
  name: 'John',
  email: 'john@example.com',
  age: 30
};

console.log(GenericUtils.pick(user, ['id', 'name'])); // { id: 1, name: 'John' }
console.log(GenericUtils.omit(user, ['email', 'age'])); // { id: 1, name: 'John' }

const readonlyUser = GenericUtils.readonly(user);
// readonlyUser.name = 'Bob'; // 在严格模式下会抛出错误

三、装饰器的实现原理

装饰器基础实现
// 3.1 基础装饰器工厂
function createDecorator(decoratorFunc) {
  return function(...args) {
    // 类装饰器
    if (args.length === 1 && typeof args[0] === 'function') {
      const targetClass = args[0];
      return decoratorFunc(targetClass) || targetClass;
    }
    
    // 方法装饰器
    if (args.length === 3 && typeof args[2] === 'object') {
      const [target, property, descriptor] = args;
      return decoratorFunc(target, property, descriptor) || descriptor;
    }
    
    // 属性装饰器
    if (args.length === 2 && typeof args[1] === 'string') {
      const [target, property] = args;
      decoratorFunc(target, property);
      return;
    }
    
    // 参数装饰器
    if (args.length === 3 && typeof args[2] === 'number') {
      const [target, property, parameterIndex] = args;
      decoratorFunc(target, property, parameterIndex);
      return;
    }
    
    return decoratorFunc(...args);
  };
}

// 3.2 类装饰器
function classDecorator(logMessage) {
  return createDecorator((targetClass) => {
    // 保存原始构造函数
    const originalConstructor = targetClass;
    
    // 创建新的构造函数
    const newConstructor = function(...args) {
      console.log(`${logMessage}: 创建 ${originalConstructor.name} 实例`);
      const instance = new originalConstructor(...args);
      
      // 可以在这里修改实例
      if (logMessage.includes('sealed')) {
        Object.seal(instance);
      }
      
      return instance;
    };
    
    // 复制原型链
    newConstructor.prototype = originalConstructor.prototype;
    
    // 复制静态属性
    Object.setPrototypeOf(newConstructor, originalConstructor);
    
    return newConstructor;
  });
}

// 3.3 方法装饰器
function methodDecorator(options = {}) {
  return createDecorator((target, property, descriptor) => {
    const originalMethod = descriptor.value;
    
    descriptor.value = function(...args) {
      // 前置处理
      if (options.log) {
        console.log(`调用方法: ${property}, 参数:`, args);
      }
      
      if (options.measureTime) {
        console.time(`方法 ${property} 执行时间`);
      }
      
      // 执行原始方法
      const result = originalMethod.apply(this, args);
      
      // 后置处理
      if (options.measureTime) {
        console.timeEnd(`方法 ${property} 执行时间`);
      }
      
      if (options.log) {
        console.log(`方法 ${property} 返回:`, result);
      }
      
      return result;
    };
    
    return descriptor;
  });
}

// 3.4 属性装饰器
function propertyDecorator(defaultValue) {
  return createDecorator((target, property) => {
    // 创建私有属性名称
    const privateProp = `_${property}`;
    
    // 定义getter和setter
    Object.defineProperty(target, property, {
      get() {
        return this[privateProp] !== undefined ? this[privateProp] : defaultValue;
      },
      set(value) {
        this[privateProp] = value;
      },
      enumerable: true,
      configurable: true
    });
  });
}

// 3.5 参数装饰器
function parameterDecorator(validator) {
  return createDecorator((target, property, parameterIndex) => {
    // 获取方法的参数验证元数据
    if (!target.__parameterValidations) {
      target.__parameterValidations = new Map();
    }
    
    const key = `${property}_${parameterIndex}`;
    target.__parameterValidations.set(key, validator);
    
    // 重写方法以添加参数验证
    const originalMethod = target[property];
    
    target[property] = function(...args) {
      // 验证参数
      const validator = target.__parameterValidations.get(`${property}_${parameterIndex}`);
      if (validator && !validator(args[parameterIndex])) {
        throw new Error(`参数 ${parameterIndex} 验证失败`);
      }
      
      return originalMethod.apply(this, args);
    };
  });
}

// 使用示例
@classDecorator('自动日志记录 - sealed')
class UserService {
  @propertyDecorator('guest')
  role;
  
  constructor(name) {
    this.name = name;
  }
  
  @methodDecorator({ log: true, measureTime: true })
  greet(@parameterDecorator(val => typeof val === 'string') message) {
    return `${this.name} 说: ${message}`;
  }
  
  @methodDecorator({ log: true })
  setRole(@parameterDecorator(role => ['admin', 'user', 'guest'].includes(role)) newRole) {
    this.role = newRole;
  }
}

const service = new UserService('Alice');
console.log(service.role); // "guest" (默认值)
service.setRole('admin');
console.log(service.greet('你好!')); // 输出日志和结果
高级装饰器模式
// 3.6 依赖注入装饰器
class DependencyContainer {
  static dependencies = new Map();
  
  static register(token, implementation) {
    this.dependencies.set(token, implementation);
  }
  
  static resolve(token) {
    const dependency = this.dependencies.get(token);
    if (!dependency) {
      throw new Error(`未找到依赖: ${token}`);
    }
    
    if (typeof dependency === 'function') {
      return new dependency();
    }
    
    return dependency;
  }
}

function inject(token) {
  return createDecorator((target, property, descriptor) => {
    if (descriptor) {
      // 方法参数注入
      const originalMethod = descriptor.value;
      
      descriptor.value = function(...args) {
        // 解析依赖
        const dependency = DependencyContainer.resolve(token);
        return originalMethod.call(this, dependency, ...args);
      };
      
      return descriptor;
    } else {
      // 属性注入
      return {
        get() {
          return DependencyContainer.resolve(token);
        },
        enumerable: true,
        configurable: true
      };
    }
  });
}

// 3.7 路由装饰器(类似Angular/NestJS)
class Router {
  static routes = new Map();
  
  static get(path) {
    return createDecorator((target, property, descriptor) => {
      const originalMethod = descriptor.value;
      const routeKey = `GET ${path}`;
      
      this.routes.set(routeKey, {
        controller: target.constructor.name,
        method: property,
        handler: originalMethod
      });
      
      descriptor.value = function(...args) {
        console.log(`路由: ${routeKey}`);
        return originalMethod.apply(this, args);
      };
      
      return descriptor;
    });
  }
  
  static post(path) {
    return createDecorator((target, property, descriptor) => {
      const originalMethod = descriptor.value;
      const routeKey = `POST ${path}`;
      
      this.routes.set(routeKey, {
        controller: target.constructor.name,
        method: property,
        handler: originalMethod
      });
      
      return descriptor;
    });
  }
  
  static handleRequest(method, path) {
    const routeKey = `${method} ${path}`;
    const route = this.routes.get(routeKey);
    
    if (route) {
      console.log(`处理请求: ${routeKey}`);
      // 实际中会创建控制器实例并调用方法
      return route.handler;
    }
    
    return null;
  }
}

// 3.8 验证装饰器
class Validator {
  static validate(target, property, value) {
    const validations = target.constructor.__validations;
    if (validations && validations[property]) {
      for (const validation of validations[property]) {
        if (!validation.validator(value)) {
          throw new Error(validation.message || `验证失败: ${property}`);
        }
      }
    }
    return true;
  }
  
  static required(message = '该字段是必填的') {
    return createDecorator((target, property, descriptor) => {
      if (descriptor) {
        // 方法参数验证
        const originalMethod = descriptor.value;
        
        descriptor.value = function(...args) {
          const value = args[0];
          if (!value && value !== 0 && value !== false) {
            throw new Error(message);
          }
          return originalMethod.apply(this, args);
        };
        
        return descriptor;
      } else {
        // 属性验证
        if (!target.constructor.__validations) {
          target.constructor.__validations = {};
        }
        
        if (!target.constructor.__validations[property]) {
          target.constructor.__validations[property] = [];
        }
        
        target.constructor.__validations[property].push({
          validator: value => value != null && value !== '',
          message
        });
        
        // 创建getter/setter
        const privateProp = `_${property}`;
        
        return {
          get() {
            return this[privateProp];
          },
          set(value) {
            this[privateProp] = value;
          },
          enumerable: true,
          configurable: true
        };
      }
    });
  }
  
  static minLength(length, message) {
    return createDecorator((target, property) => {
      if (!target.constructor.__validations) {
        target.constructor.__validations = {};
      }
      
      if (!target.constructor.__validations[property]) {
        target.constructor.__validations[property] = [];
      }
      
      target.constructor.__validations[property].push({
        validator: value => !value || value.length >= length,
        message: message || `长度不能少于 ${length} 个字符`
      });
    });
  }
  
  static maxLength(length, message) {
    return createDecorator((target, property) => {
      if (!target.constructor.__validations) {
        target.constructor.__validations = {};
      }
      
      if (!target.constructor.__validations[property]) {
        target.constructor.__validations[property] = [];
      }
      
      target.constructor.__validations[property].push({
        validator: value => !value || value.length <= length,
        message: message || `长度不能超过 ${length} 个字符`
      });
    });
  }
}

// 使用高级装饰器
@classDecorator('用户控制器')
class UserController {
  @Router.get('/users')
  getAllUsers() {
    return ['Alice', 'Bob', 'Charlie'];
  }
  
  @Router.post('/users')
  createUser(@Validator.required() name) {
    return { id: 1, name };
  }
}

// 用户模型
class User {
  @Validator.required('用户名是必填的')
  @Validator.minLength(3, '用户名至少3个字符')
  @Validator.maxLength(20, '用户名最多20个字符')
  username;
  
  @Validator.required('密码是必填的')
  @Validator.minLength(6, '密码至少6个字符')
  password;
  
  constructor(username, password) {
    this.username = username;
    this.password = password;
  }
  
  validate() {
    for (const prop in this) {
      if (this.hasOwnProperty(prop)) {
        Validator.validate(this, prop, this[prop]);
      }
    }
  }
}

// 测试
const user = new User('alice', 'password123');
user.validate(); // 成功

try {
  const invalidUser = new User('a', '123');
  invalidUser.validate(); // 抛出错误
} catch (error) {
  console.error(error.message);
}

四、类型推断与类型系统

类型推断实现
// 4.1 类型推断引擎
class TypeInferenceEngine {
  constructor() {
    this.typeRegistry = new Map();
    this.variableTypes = new Map();
  }
  
  // 推断变量类型
  inferVariableType(name, value) {
    let inferredType = this.inferValueType(value);
    
    // 检查是否已经声明过类型
    if (this.variableTypes.has(name)) {
      const declaredType = this.variableTypes.get(name);
      if (!this.isCompatible(inferredType, declaredType)) {
        throw new Error(`类型不匹配: 变量 ${name} 声明为 ${declaredType}, 但推断为 ${inferredType}`);
      }
      return declaredType;
    }
    
    // 记录推断的类型
    this.variableTypes.set(name, inferredType);
    return inferredType;
  }
  
  // 推断值类型
  inferValueType(value) {
    if (value === null) return 'null';
    if (value === undefined) return 'undefined';
    
    const type = typeof value;
    
    if (type === 'object') {
      if (Array.isArray(value)) {
        // 推断数组元素类型
        if (value.length === 0) return 'any[]';
        const elementType = this.inferValueType(value[0]);
        return `${elementType}[]`;
      }
      
      if (value instanceof Date) return 'Date';
      if (value instanceof RegExp) return 'RegExp';
      
      // 推断对象结构
      const structure = {};
      for (const key in value) {
        if (value.hasOwnProperty(key)) {
          structure[key] = this.inferValueType(value[key]);
        }
      }
      return JSON.stringify(structure);
    }
    
    return type;
  }
  
  // 检查类型兼容性
  isCompatible(type1, type2) {
    if (type1 === type2) return true;
    
    // 处理any类型
    if (type1 === 'any' || type2 === 'any') return true;
    
    // 处理数组类型
    if (type1.endsWith('[]') && type2.endsWith('[]')) {
      const elementType1 = type1.slice(0, -2);
      const elementType2 = type2.slice(0, -2);
      return this.isCompatible(elementType1, elementType2);
    }
    
    // 处理对象类型
    if (type1.startsWith('{') && type2.startsWith('{')) {
      try {
        const obj1 = JSON.parse(type1);
        const obj2 = JSON.parse(type2);
        
        for (const key in obj1) {
          if (obj1.hasOwnProperty(key)) {
            if (!obj2[key] || !this.isCompatible(obj1[key], obj2[key])) {
              return false;
            }
          }
        }
        return true;
      } catch {
        return false;
      }
    }
    
    return false;
  }
  
  // 推断函数返回类型
  inferFunctionReturn(func, args) {
    try {
      const result = func.apply(null, args);
      return this.inferValueType(result);
    } catch {
      return 'any';
    }
  }
}

// 使用示例
const engine = new TypeInferenceEngine();

const variables = {
  name: 'Alice',
  age: 30,
  scores: [95, 88, 92],
  profile: {
    email: 'alice@example.com',
    active: true
  }
};

for (const [name, value] of Object.entries(variables)) {
  const type = engine.inferVariableType(name, value);
  console.log(`${name}: ${type}`);
}

// 4.2 联合类型推断
function inferUnionType(values) {
  const types = new Set();
  
  for (const value of values) {
    const engine = new TypeInferenceEngine();
    types.add(engine.inferValueType(value));
  }
  
  return Array.from(types).join(' | ');
}

console.log(inferUnionType([1, 'hello', true])); // "number | string | boolean"

// 4.3 上下文类型推断
class ContextualTyping {
  static inferWithContext(value, context) {
    const engine = new TypeInferenceEngine();
    const valueType = engine.inferValueType(value);
    
    // 如果有上下文类型,检查兼容性
    if (context.expectedType) {
      if (!engine.isCompatible(valueType, context.expectedType)) {
        throw new Error(`上下文类型不匹配: 期望 ${context.expectedType}, 实际 ${valueType}`);
      }
      return context.expectedType;
    }
    
    return valueType;
  }
}

const context = { expectedType: 'string' };
console.log(ContextualTyping.inferWithContext('hello', context)); // "string"
// ContextualTyping.inferWithContext(123, context); // 抛出错误
高级类型系统
// 4.4 条件类型模拟
class ConditionalType {
  static extends(T, U) {
    // 简化实现:检查T是否可以赋值给U
    return T === U || T === 'any';
  }
  
  static extract(T, U) {
    // 模拟 Extract<T, U>
    if (this.extends(T, U)) {
      return T;
    }
    return 'never';
  }
  
  static exclude(T, U) {
    // 模拟 Exclude<T, U>
    if (this.extends(T, U)) {
      return 'never';
    }
    return T;
  }
  
  static nonNullable(T) {
    // 模拟 NonNullable<T>
    if (T === 'null' || T === 'undefined') {
      return 'never';
    }
    return T;
  }
  
  static returnType(func) {
    // 模拟 ReturnType<T>
    try {
      const result = func();
      const engine = new TypeInferenceEngine();
      return engine.inferValueType(result);
    } catch {
      return 'any';
    }
  }
  
  static parameters(func) {
    // 模拟 Parameters<T>
    const funcStr = func.toString();
    const paramMatch = funcStr.match(/\(([^)]*)\)/);
    
    if (paramMatch) {
      const params = paramMatch[1].split(',').map(p => p.trim());
      return params.map(param => {
        const [name, type] = param.split(':').map(s => s.trim());
        return type || 'any';
      });
    }
    
    return [];
  }
}

// 使用示例
console.log(ConditionalType.extends('string', 'string')); // true
console.log(ConditionalType.extract('string | number', 'string')); // "string"
console.log(ConditionalType.exclude('string | number', 'string')); // "number"
console.log(ConditionalType.nonNullable('string | null')); // "string"

function sampleFunc(x, y) {
  return x + y;
}

console.log(ConditionalType.returnType(() => sampleFunc(1, 2))); // "number"
console.log(ConditionalType.parameters(sampleFunc)); // ["any", "any"]

// 4.5 映射类型模拟
class MappedType {
  static partial(T) {
    // 模拟 Partial<T>
    if (typeof T === 'string' && T.startsWith('{')) {
      try {
        const obj = JSON.parse(T);
        const result = {};
        for (const key in obj) {
          result[key] = obj[key] + '?'; // 添加可选标记
        }
        return JSON.stringify(result);
      } catch {
        return T;
      }
    }
    return T;
  }
  
  static required(T) {
    // 模拟 Required<T>
    if (typeof T === 'string' && T.startsWith('{')) {
      try {
        const obj = JSON.parse(T);
        const result = {};
        for (const key in obj) {
          const type = obj[key].endsWith('?') ? obj[key].slice(0, -1) : obj[key];
          result[key] = type;
        }
        return JSON.stringify(result);
      } catch {
        return T;
      }
    }
    return T;
  }
  
  static readonly(T) {
    // 模拟 Readonly<T>
    if (typeof T === 'string' && T.startsWith('{')) {
      try {
        const obj = JSON.parse(T);
        const result = {};
        for (const key in obj) {
          result[key] = 'readonly ' + obj[key];
        }
        return JSON.stringify(result);
      } catch {
        return T;
      }
    }
    return T;
  }
  
  static record(K, T) {
    // 模拟 Record<K, T>
    const keys = K.split(' | ');
    const result = {};
    keys.forEach(key => {
      const cleanKey = key.replace(/['"]/g, '');
      result[cleanKey] = T;
    });
    return JSON.stringify(result);
  }
}

// 使用示例
const userType = JSON.stringify({
  name: 'string',
  age: 'number?',
  email: 'string'
});

console.log('Partial:', MappedType.partial(userType));
console.log('Required:', MappedType.required(userType));
console.log('Readonly:', MappedType.readonly(userType));
console.log('Record:', MappedType.record('"id" | "name"', 'string'));

五、模块与命名空间

TypeScript模块系统
// 5.1 模块加载器模拟
class TypeScriptModuleLoader {
  constructor() {
    this.modules = new Map();
    this.exports = new Map();
    this.moduleCache = new Map();
  }
  
  // 定义模块
  define(moduleId, dependencies, factory) {
    this.modules.set(moduleId, {
      dependencies,
      factory,
      exports: {},
      resolved: false
    });
  }
  
  // 解析模块
  async require(moduleId) {
    if (this.moduleCache.has(moduleId)) {
      return this.moduleCache.get(moduleId);
    }
    
    const module = this.modules.get(moduleId);
    if (!module) {
      // 尝试作为外部模块加载
      return this.loadExternalModule(moduleId);
    }
    
    // 解析依赖
    const depPromises = module.dependencies.map(dep => {
      if (dep === 'exports') return {};
      if (dep === 'require') return this.require.bind(this);
      if (dep === 'module') return { id: moduleId, exports: {} };
      return this.require(dep);
    });
    
    const dependencies = await Promise.all(depPromises);
    
    // 执行工厂函数
    const exports = module.factory.apply(null, dependencies);
    
    // 缓存结果
    module.exports = exports || {};
    module.resolved = true;
    this.moduleCache.set(moduleId, module.exports);
    
    return module.exports;
  }
  
  // 加载外部模块(模拟)
  async loadExternalModule(moduleId) {
    console.log(`加载外部模块: ${moduleId}`);
    
    // 模拟动态导入
    if (moduleId.startsWith('.')) {
      // 相对路径
      const mockModule = await this.mockLoadModule(moduleId);
      return mockModule;
    }
    
    // 假设是npm包
    return {};
  }
  
  async mockLoadModule(path) {
    // 模拟模块内容
    const mockModules = {
      './math': {
        add: (a, b) => a + b,
        subtract: (a, b) => a - b
      },
      './utils': {
        format: str => str.toUpperCase(),
        parse: str => JSON.parse(str)
      }
    };
    
    await new Promise(resolve => setTimeout(resolve, 100)); // 模拟延迟
    
    return mockModules[path] || {};
  }
  
  // 编译TypeScript模块
  compileModule(source) {
    // 移除类型注解
    const jsCode = source
      .replace(/:\s*\w+(?:<[^>]*>)?(?=\s*[;,=){}])/g, '') // 移除类型注解
      .replace(/export\s+(?:default\s+)?/g, '') // 简化导出
      .replace(/import\s+.*?from\s+['"](.+)['"]/g, '// 导入: $1'); // 注释化导入
    
    return jsCode;
  }
}

// 使用示例
const loader = new TypeScriptModuleLoader();

// 定义TypeScript模块
const mathSource = `
export function add(a: number, b: number): number {
  return a + b;
}

export function subtract(a: number, b: number): number {
  return a - b;
}

export default class Calculator {
  multiply(a: number, b: number): number {
    return a * b;
  }
}
`;

const appSource = `
import { add } from './math';
import Calculator from './math';

export function calculate(): number {
  const calc = new Calculator();
  return add(10, calc.multiply(2, 3));
}
`;

// 编译模块
const mathJS = loader.compileModule(mathSource);
const appJS = loader.compileModule(appSource);

console.log('编译后的math模块:');
console.log(mathJS);

console.log('编译后的app模块:');
console.log(appJS);

// 5.2 命名空间实现
class NamespaceManager {
  static namespaces = new Map();
  
  static create(namespace, contents) {
    if (!this.namespaces.has(namespace)) {
      this.namespaces.set(namespace, {});
    }
    
    const ns = this.namespaces.get(namespace);
    Object.assign(ns, contents);
    
    // 暴露到全局
    const parts = namespace.split('.');
    let current = globalThis;
    
    for (let i = 0; i < parts.length; i++) {
      const part = parts[i];
      if (i === parts.length - 1) {
        current[part] = ns;
      } else {
        current[part] = current[part] || {};
        current = current[part];
      }
    }
    
    return ns;
  }
  
  static get(namespace) {
    return this.namespaces.get(namespace);
  }
  
  static export(namespace, exports) {
    const ns = this.get(namespace) || this.create(namespace, {});
    Object.assign(ns, exports);
  }
}

// 使用命名空间
NamespaceManager.create('MyApp.Math', {
  add: (a, b) => a + b,
  subtract: (a, b) => a - b,
  constants: {
    PI: 3.14159,
    E: 2.71828
  }
});

NamespaceManager.create('MyApp.Utils', {
  format: str => str.toUpperCase(),
  validate: obj => obj != null
});

// 访问命名空间
console.log(MyApp.Math.add(2, 3)); // 5
console.log(MyApp.Utils.format('hello')); // "HELLO"

六、工程化与构建工具集成

TypeScript配置与编译
// 6.1 TypeScript配置解析器
class TSConfigParser {
  static parse(config) {
    const defaults = {
      compilerOptions: {
        target: 'es5',
        module: 'commonjs',
        strict: false,
        esModuleInterop: true,
        skipLibCheck: true,
        forceConsistentCasingInFileNames: true
      },
      include: ['src/**/*'],
      exclude: ['node_modules', 'dist']
    };
    
    return this.deepMerge(defaults, config);
  }
  
  static deepMerge(target, source) {
    for (const key in source) {
      if (source.hasOwnProperty(key)) {
        if (this.isObject(source[key]) && this.isObject(target[key])) {
          this.deepMerge(target[key], source[key]);
        } else {
          target[key] = source[key];
        }
      }
    }
    return target;
  }
  
  static isObject(item) {
    return item && typeof item === 'object' && !Array.isArray(item);
  }
  
  static generateCompilerCommand(config) {
    const options = config.compilerOptions;
    const args = [];
    
    for (const [key, value] of Object.entries(options)) {
      const argName = `--${key}`;
      
      if (typeof value === 'boolean') {
        if (value) args.push(argName);
      } else if (typeof value === 'string') {
        args.push(`${argName} ${value}`);
      } else if (Array.isArray(value)) {
        args.push(`${argName} ${value.join(',')}`);
      }
    }
    
    return `tsc ${args.join(' ')}`;
  }
}

// 示例配置
const tsconfig = {
  compilerOptions: {
    target: 'es2020',
    module: 'esnext',
    lib: ['es2020', 'dom'],
    outDir: './dist',
    rootDir: './src',
    strict: true,
    moduleResolution: 'node',
    baseUrl: '.',
    paths: {
      '@/*': ['src/*']
    },
    allowSyntheticDefaultImports: true
  },
  include: ['src/**/*.ts', 'src/**/*.tsx'],
  exclude: ['node_modules']
};

const parsedConfig = TSConfigParser.parse(tsconfig);
console.log('解析后的配置:', parsedConfig);
console.log('编译器命令:', TSConfigParser.generateCompilerCommand(parsedConfig));

// 6.2 构建管道模拟
class TypeScriptBuildPipeline {
  constructor(config) {
    this.config = config;
    this.steps = [];
  }
  
  addStep(name, processor) {
    this.steps.push({ name, processor });
    return this;
  }
  
  async build(sourceFiles) {
    console.log('开始构建TypeScript项目...');
    
    let processedFiles = sourceFiles;
    
    for (const step of this.steps) {
      console.log(`执行步骤: ${step.name}`);
      
      if (Array.isArray(processedFiles)) {
        const results = await Promise.all(
          processedFiles.map(file => step.processor(file, this.config))
        );
        processedFiles = results;
      } else {
        processedFiles = await step.processor(processedFiles, this.config);
      }
    }
    
    console.log('构建完成!');
    return processedFiles;
  }
}

// 构建步骤处理器
const processors = {
  // 类型检查
  typeCheck: async (file, config) => {
    console.log(`类型检查: ${file.name}`);
    // 模拟类型检查
    if (file.name.includes('error')) {
      throw new Error(`类型错误: ${file.name}`);
    }
    return file;
  },
  
  // 编译
  compile: async (file, config) => {
    console.log(`编译: ${file.name}`);
    
    // 模拟编译过程
    const jsCode = file.content
      .replace(/:\s*\w+/g, '') // 移除类型注解
      .replace(/interface\s+\w+\s*\{[^}]+\}/g, '') // 移除接口
      .replace(/export\s+type\s+\w+/g, '') // 移除类型导出
      .trim();
    
    return {
      ...file,
      content: jsCode,
      extension: '.js'
    };
  },
  
  // 打包
  bundle: async (files, config) => {
    console.log('打包文件...');
    
    const bundleContent = files
      .map(file => `// ${file.name}\n${file.content}`)
      .join('\n\n');
    
    return {
      name: 'bundle.js',
      content: bundleContent,
      size: bundleContent.length
    };
  },
  
  // 压缩
  minify: async (file, config) => {
    console.log('压缩代码...');
    
    // 简单压缩:移除空格和注释
    const minified = file.content
      .replace(/\/\/.*$/gm, '')
      .replace(/\/\*[\s\S]*?\*\//g, '')
      .replace(/\s+/g, ' ')
      .trim();
    
    return {
      ...file,
      content: minified,
      size: minified.length
    };
  }
};

// 模拟源文件
const sourceFiles = [
  {
    name: 'math.ts',
    content: `
      export function add(a: number, b: number): number {
        return a + b;
      }
      
      export function subtract(a: number, b: number): number {
        return a - b;
      }
    `
  },
  {
    name: 'app.ts',
    content: `
      import { add } from './math';
      
      export function calculate(): number {
        return add(1, 2);
      }
    `
  }
];

// 创建构建管道
const pipeline = new TypeScriptBuildPipeline(tsconfig)
  .addStep('类型检查', processors.typeCheck)
  .addStep('编译', processors.compile)
  .addStep('打包', processors.bundle)
  .addStep('压缩', processors.minify);

// 执行构建
pipeline.build(sourceFiles).then(result => {
  console.log('构建结果:', result);
});

七、实战应用: 在JavaScript项目中引入TypeScript

渐进式迁移策略
// 7.1 混合项目结构管理
class HybridProjectManager {
  constructor(options = {}) {
    this.options = {
      tsDir: 'src/ts',
      jsDir: 'src/js',
      buildDir: 'dist',
      allowJS: true,
      checkJS: true,
      ...options
    };
    
    this.fileRegistry = new Map();
  }
  
  // 注册文件
  registerFile(path, type) {
    this.fileRegistry.set(path, {
      type,
      dependencies: [],
      errors: []
    });
    
    // 自动检测文件类型
    if (path.endsWith('.ts') || path.endsWith('.tsx')) {
      this.fileRegistry.get(path).type = 'typescript';
    } else if (path.endsWith('.js') || path.endsWith('.jsx')) {
      this.fileRegistry.get(path).type = 'javascript';
    }
  }
  
  // 分析依赖关系
  analyzeDependencies(path) {
    const file = this.fileRegistry.get(path);
    if (!file) return;
    
    const content = this.readFile(path);
    const dependencies = [];
    
    // 解析导入语句
    const importRegex = /import\s+(?:.*?from\s+)?['"]([^'"]+)['"]/g;
    let match;
    
    while ((match = importRegex.exec(content)) !== null) {
      dependencies.push(match[1]);
    }
    
    file.dependencies = dependencies;
  }
  
  // 检查混合项目问题
  checkHybridIssues() {
    const issues = [];
    
    for (const [path, file] of this.fileRegistry) {
      // 检查TypeScript文件是否导入了未定义的JavaScript模块
      if (file.type === 'typescript') {
        for (const dep of file.dependencies) {
          if (dep.endsWith('.js')) {
            const depPath = this.resolvePath(path, dep);
            const depFile = this.fileRegistry.get(depPath);
            
            if (depFile && depFile.type === 'javascript') {
              issues.push({
                type: 'ts-imports-js',
                message: `TypeScript文件 ${path} 导入了JavaScript文件 ${depPath}`,
                severity: 'warning',
                suggestion: '考虑将JavaScript文件迁移为TypeScript或添加类型声明'
              });
            }
          }
        }
      }
      
      // 检查JavaScript文件是否缺少JSDoc注释
      if (file.type === 'javascript' && this.options.checkJS) {
        const content = this.readFile(path);
        const hasJSDoc = /\/\*\*\s*\n(?:[^*]|\*(?!\/))*\*\//.test(content);
        
        if (!hasJSDoc) {
          issues.push({
            type: 'missing-jsdoc',
            message: `JavaScript文件 ${path} 缺少JSDoc注释`,
            severity: 'info',
            suggestion: '添加JSDoc注释以提供类型信息'
          });
        }
      }
    }
    
    return issues;
  }
  
  // 生成迁移建议
  generateMigrationPlan() {
    const plan = {
      phase1: [], // 立即迁移的文件
      phase2: [], // 可以稍后迁移的文件
      declarations: [] // 需要创建的类型声明文件
    };
    
    for (const [path, file] of this.fileRegistry) {
      if (file.type === 'javascript') {
        // 分析复杂性
        const complexity = this.assessComplexity(path);
        
        if (complexity <= 2) {
          plan.phase1.push(path);
        } else {
          plan.phase2.push(path);
        }
        
        // 检查是否需要声明文件
        if (file.dependencies.some(dep => dep.startsWith('@types/'))) {
          plan.declarations.push(path);
        }
      }
    }
    
    return plan;
  }
  
  // 评估文件复杂性
  assessComplexity(path) {
    const content = this.readFile(path);
    let score = 0;
    
    // 基于行数
    const lines = content.split('\n').length;
    if (lines > 100) score += 2;
    else if (lines > 50) score += 1;
    
    // 基于函数数量
    const functionCount = (content.match(/function\s+\w+|\b\w+\s*=/g) || []).length;
    score += Math.min(Math.floor(functionCount / 5), 3);
    
    // 基于外部依赖
    const importCount = (content.match(/import\s+|require\(/g) || []).length;
    score += Math.min(importCount, 2);
    
    return score;
  }
  
  // 工具方法
  readFile(path) {
    // 模拟文件读取
    return '模拟文件内容';
  }
  
  resolvePath(base, relative) {
    // 简化路径解析
    return relative;
  }
}

// 使用示例
const manager = new HybridProjectManager({
  tsDir: 'src/ts',
  jsDir: 'src/js',
  checkJS: true
});

// 注册文件
manager.registerFile('src/js/user.js', 'javascript');
manager.registerFile('src/ts/auth.ts', 'typescript');
manager.registerFile('src/js/utils.js', 'javascript');

// 分析问题
const issues = manager.checkHybridIssues();
console.log('发现的问题:', issues);

// 生成迁移计划
const migrationPlan = manager.generateMigrationPlan();
console.log('迁移计划:', migrationPlan);

// 7.2 类型声明生成器
class TypeDeclarationGenerator {
  static generateFromJS(jsCode, options = {}) {
    const declarations = [];
    
    // 解析函数
    const functionRegex = /function\s+(\w+)\s*\(([^)]*)\)/g;
    let match;
    
    while ((match = functionRegex.exec(jsCode)) !== null) {
      const [, funcName, params] = match;
      const paramTypes = this.inferParamTypes(params);
      const returnType = this.inferReturnType(jsCode, funcName);
      
      declarations.push(
        `declare function ${funcName}(${paramTypes}): ${returnType};`
      );
    }
    
    // 解析类
    const classRegex = /class\s+(\w+)/g;
    while ((match = classRegex.exec(jsCode)) !== null) {
      const [, className] = match;
      const classDeclaration = this.generateClassDeclaration(jsCode, className);
      declarations.push(classDeclaration);
    }
    
    // 解析变量导出
    const exportRegex = /exports\.(\w+)\s*=/g;
    while ((match = exportRegex.exec(jsCode)) !== null) {
      const [, exportName] = match;
      const type = this.inferVariableType(jsCode, exportName);
      declarations.push(`declare const ${exportName}: ${type};`);
    }
    
    return declarations.join('\n');
  }
  
  static inferParamTypes(paramsStr) {
    const params = paramsStr.split(',').map(p => p.trim()).filter(p => p);
    
    return params.map((param, index) => {
      const [name, defaultValue] = param.split('=').map(s => s.trim());
      let type = 'any';
      
      if (defaultValue) {
        if (defaultValue.includes("'") || defaultValue.includes('"')) {
          type = 'string';
        } else if (defaultValue === 'true' || defaultValue === 'false') {
          type = 'boolean';
        } else if (!isNaN(parseFloat(defaultValue))) {
          type = 'number';
        } else if (defaultValue === '[]') {
          type = 'any[]';
        } else if (defaultValue === '{}') {
          type = 'object';
        }
      }
      
      return `${name}: ${type}`;
    }).join(', ');
  }
  
  static inferReturnType(jsCode, funcName) {
    // 简化实现:检查return语句
    const returnRegex = new RegExp(`function\\s+${funcName}[^{]*{([^}]*return[^;]+;)?`, 'i');
    const match = jsCode.match(returnRegex);
    
    if (match && match[1]) {
      const returnExpr = match[1].replace('return', '').trim();
      
      if (returnExpr.includes("'") || returnExpr.includes('"')) {
        return 'string';
      } else if (returnExpr === 'true' || returnExpr === 'false') {
        return 'boolean';
      } else if (!isNaN(parseFloat(returnExpr))) {
        return 'number';
      }
    }
    
    return 'any';
  }
  
  static generateClassDeclaration(jsCode, className) {
    const declaration = [`declare class ${className} {`];
    
    // 提取构造函数
    const constructorRegex = new RegExp(`constructor\\(([^)]*)\\)`, 'g');
    const constructorMatch = constructorRegex.exec(jsCode);
    
    if (constructorMatch) {
      const params = constructorMatch[1];
      const paramTypes = this.inferParamTypes(params);
      declaration.push(`  constructor(${paramTypes});`);
    }
    
    // 提取方法
    const methodRegex = new RegExp(`${className}\\.prototype\\.(\\w+)\\s*=\\s*function`, 'g');
    while ((match = methodRegex.exec(jsCode)) !== null) {
      const [, methodName] = match;
      declaration.push(`  ${methodName}(): any;`);
    }
    
    declaration.push('}');
    return declaration.join('\n');
  }
  
  static inferVariableType(jsCode, varName) {
    const regex = new RegExp(`${varName}\\s*=\\s*([^;]+)`, 'g');
    const match = regex.exec(jsCode);
    
    if (match) {
      const value = match[1].trim();
      
      if (value.startsWith('[')) return 'any[]';
      if (value.startsWith('{')) return 'object';
      if (value.includes("'") || value.includes('"')) return 'string';
      if (value === 'true' || value === 'false') return 'boolean';
      if (!isNaN(parseFloat(value))) return 'number';
    }
    
    return 'any';
  }
}

// 生成类型声明示例
const jsCode = `
function greet(name) {
  return 'Hello, ' + name;
}

class User {
  constructor(name, age = 18) {
    this.name = name;
    this.age = age;
  }
  
  sayHello() {
    return greet(this.name);
  }
}

exports.greet = greet;
exports.User = User;
exports.VERSION = '1.0.0';
`;

const declarations = TypeDeclarationGenerator.generateFromJS(jsCode);
console.log('生成的类型声明:');
console.log(declarations);

八、性能优化与最佳实践

TypeScript编译优化
// 8.1 增量编译
class IncrementalCompiler {
  constructor() {
    this.fileCache = new Map();
    this.dependencyGraph = new Map();
    this.lastCompileTime = Date.now();
  }
  
  // 检查文件是否需要重新编译
  needsRecompile(filePath, content) {
    const cached = this.fileCache.get(filePath);
    
    if (!cached) {
      return true; // 新文件
    }
    
    if (cached.content !== content) {
      return true; // 内容改变
    }
    
    // 检查依赖是否改变
    const dependencies = this.dependencyGraph.get(filePath) || [];
    for (const dep of dependencies) {
      const depCached = this.fileCache.get(dep);
      if (!depCached || depCached.timestamp > cached.timestamp) {
        return true; // 依赖已更新
      }
    }
    
    return false; // 无需重新编译
  }
  
  // 增量编译
  incrementalCompile(files) {
    const toCompile = [];
    const startTime = Date.now();
    
    for (const file of files) {
      if (this.needsRecompile(file.path, file.content)) {
        toCompile.push(file);
      }
    }
    
    console.log(`需要重新编译 ${toCompile.length} 个文件`);
    
    if (toCompile.length === 0) {
      console.log('没有文件需要重新编译,使用缓存');
      return this.getCachedOutput();
    }
    
    // 执行编译
    const results = this.compileFiles(toCompile);
    
    // 更新缓存
    for (const file of toCompile) {
      this.fileCache.set(file.path, {
        content: file.content,
        timestamp: startTime,
        output: results[file.path]
      });
    }
    
    this.lastCompileTime = startTime;
    
    return results;
  }
  
  compileFiles(files) {
    // 简化编译过程
    const results = {};
    
    for (const file of files) {
      results[file.path] = file.content.replace(/:\s*\w+/g, '');
    }
    
    return results;
  }
  
  getCachedOutput() {
    const output = {};
    
    for (const [path, cached] of this.fileCache) {
      output[path] = cached.output;
    }
    
    return output;
  }
}

// 8.2 项目引用优化
class ProjectReferenceOptimizer {
  static optimize(config, projects) {
    const optimized = { ...config };
    
    // 分析项目依赖
    const dependencies = this.analyzeDependencies(projects);
    
    // 设置项目引用
    optimized.compilerOptions = {
      ...optimized.compilerOptions,
      composite: true,
      declaration: true,
      declarationMap: true,
      incremental: true
    };
    
    optimized.references = dependencies.map(dep => ({ path: dep }));
    
    return optimized;
  }
  
  static analyzeDependencies(projects) {
    const graph = new Map();
    
    // 构建依赖图
    for (const project of projects) {
      const deps = this.extractImports(project.source);
      graph.set(project.name, deps);
    }
    
    // 拓扑排序
    return this.topologicalSort(graph);
  }
  
  static extractImports(source) {
    const imports = [];
    const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
    let match;
    
    while ((match = importRegex.exec(source)) !== null) {
      imports.push(match[1]);
    }
    
    return imports;
  }
  
  static topologicalSort(graph) {
    const visited = new Set();
    const result = [];
    
    const visit = (node) => {
      if (visited.has(node)) return;
      visited.add(node);
      
      const dependencies = graph.get(node) || [];
      for (const dep of dependencies) {
        visit(dep);
      }
      
      result.push(node);
    };
    
    for (const node of graph.keys()) {
      visit(node);
    }
    
    return result;
  }
}

// 8.3 内存优化
class TypeScriptMemoryOptimizer {
  constructor() {
    this.memoryCache = new Map();
    this.maxCacheSize = 100;
  }
  
  // 编译结果缓存
  cacheCompilationResult(filePath, ast, diagnostics, output) {
    const cacheEntry = {
      ast,
      diagnostics,
      output,
      timestamp: Date.now(),
      size: this.calculateSize(ast) + this.calculateSize(output)
    };
    
    this.memoryCache.set(filePath, cacheEntry);
    this.cleanupCache();
  }
  
  // 获取缓存结果
  getCachedResult(filePath) {
    const cached = this.memoryCache.get(filePath);
    if (cached) {
      // 更新访问时间
      cached.timestamp = Date.now();
      return cached;
    }
    return null;
  }
  
  // 清理缓存
  cleanupCache() {
    if (this.memoryCache.size <= this.maxCacheSize) {
      return;
    }
    
    // LRU缓存清理
    const entries = Array.from(this.memoryCache.entries());
    entries.sort((a, b) => a[1].timestamp - b[1].timestamp);
    
    const toRemove = entries.slice(0, entries.length - this.maxCacheSize);
    
    for (const [key] of toRemove) {
      this.memoryCache.delete(key);
    }
  }
  
  // 计算对象大小
  calculateSize(obj) {
    const str = JSON.stringify(obj);
    return str.length * 2; // 粗略估计(UTF-16)
  }
  
  // AST节点缓存池
  createASTNodePool() {
    const pool = new Map();
    
    return {
      getNode(type, props) {
        const key = `${type}:${JSON.stringify(props)}`;
        
        if (pool.has(key)) {
          return pool.get(key);
        }
        
        const node = { type, ...props };
        pool.set(key, node);
        
        return node;
      },
      
      clear() {
        pool.clear();
      },
      
      get size() {
        return pool.size;
      }
    };
  }
}
TypeScript最佳实践
// 8.4 代码组织最佳实践
class TypeScriptBestPractices {
  static structureProject(projectType) {
    const structures = {
      library: {
        src: [
          'index.ts', // 主入口
          'types/',   // 类型定义
          'utils/',   // 工具函数
          'core/',    // 核心逻辑
          'tests/'    // 测试文件
        ],
        config: [
          'tsconfig.json',
          'tsconfig.build.json',
          'package.json',
          '.eslintrc.js'
        ],
        docs: 'README.md'
      },
      
      application: {
        src: [
          'main.ts',          // 应用入口
          'components/',      // 组件
          'services/',        // 服务层
          'models/',          // 数据模型
          'utils/',           // 工具函数
          'styles/',          // 样式文件
          'assets/',          // 静态资源
          'tests/'            // 测试
        ],
        config: [
          'tsconfig.json',
          'tsconfig.app.json',
          'package.json',
          'webpack.config.js'
        ],
        public: 'index.html'
      },
      
      node: {
        src: [
          'index.ts',         // 应用入口
          'controllers/',     // 控制器
          'services/',        // 服务层
          'models/',          // 数据模型
          'middleware/',      // 中间件
          'routes/',          // 路由
          'utils/',           // 工具函数
          'tests/'            // 测试
        ],
        config: [
          'tsconfig.json',
          'package.json',
          '.env',
          'dockerfile'
        ]
      }
    };
    
    return structures[projectType] || structures.library;
  }
  
  static namingConventions = {
    interfaces: {
      rule: '使用 PascalCase,以 I 开头',
      examples: ['IUser', 'IProductService', 'IRepository']
    },
    
    types: {
      rule: '使用 PascalCase',
      examples: ['UserData', 'ApiResponse', 'ConfigOptions']
    },
    
    classes: {
      rule: '使用 PascalCase',
      examples: ['UserService', 'DatabaseConnection', 'HttpClient']
    },
    
    variables: {
      rule: '使用 camelCase',
      examples: ['userName', 'productList', 'isLoading']
    },
    
    constants: {
      rule: '使用 UPPER_SNAKE_CASE',
      examples: ['MAX_RETRY_COUNT', 'API_BASE_URL', 'DEFAULT_TIMEOUT']
    },
    
    generics: {
      rule: '使用单个大写字母,T 开头',
      examples: ['T', 'K', 'V', 'TKey', 'TValue']
    }
  };
  
  static createTSConfig(projectType, options = {}) {
    const baseConfig = {
      compilerOptions: {
        target: 'es2020',
        module: 'commonjs',
        lib: ['es2020'],
        outDir: './dist',
        rootDir: './src',
        strict: true,
        esModuleInterop: true,
        skipLibCheck: true,
        forceConsistentCasingInFileNames: true
      }
    };
    
    const typeSpecific = {
      library: {
        compilerOptions: {
          declaration: true,
          declarationMap: true,
          sourceMap: true
        }
      },
      
      application: {
        compilerOptions: {
          jsx: 'react-jsx',
          moduleResolution: 'node',
          allowSyntheticDefaultImports: true
        }
      },
      
      node: {
        compilerOptions: {
          module: 'commonjs',
          target: 'es2020',
          lib: ['es2020']
        }
      }
    };
    
    return this.deepMerge(
      baseConfig,
      typeSpecific[projectType] || {},
      { compilerOptions: options }
    );
  }
  
  static deepMerge(...objects) {
    return objects.reduce((acc, obj) => {
      for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
          if (this.isObject(obj[key]) && this.isObject(acc[key])) {
            acc[key] = this.deepMerge(acc[key], obj[key]);
          } else {
            acc[key] = obj[key];
          }
        }
      }
      return acc;
    }, {});
  }
  
  static isObject(item) {
    return item && typeof item === 'object' && !Array.isArray(item);
  }
  
  // 错误处理最佳实践
  static errorHandlingPatterns = {
    // 使用Result类型处理错误
    Result: `
type Result<T, E = Error> = 
  | { success: true; data: T }
  | { success: false; error: E };

function safeOperation(): Result<string> {
  try {
    const result = riskyOperation();
    return { success: true, data: result };
  } catch (error) {
    return { success: false, error: error as Error };
  }
}
    `,
    
    // 自定义错误类
    CustomError: `
class AppError extends Error {
  constructor(
    message: string,
    public code: string,
    public statusCode: number = 500
  ) {
    super(message);
    this.name = 'AppError';
  }
}

class ValidationError extends AppError {
  constructor(message: string) {
    super(message, 'VALIDATION_ERROR', 400);
    this.name = 'ValidationError';
  }
}
    `,
    
    // 错误边界
    ErrorBoundary: `
class ErrorBoundary {
  private errorHandlers = new Map<string, (error: Error) => void>();
  
  register(component: string, handler: (error: Error) => void) {
    this.errorHandlers.set(component, handler);
  }
  
  handle(component: string, error: Error) {
    const handler = this.errorHandlers.get(component);
    if (handler) {
      handler(error);
    } else {
      console.error(\`未处理的错误 (\${component}):\`, error);
    }
  }
}
    `
  };
}

// 使用最佳实践
console.log('库项目结构:', TypeScriptBestPractices.structureProject('library'));
console.log('命名约定:', TypeScriptBestPractices.namingConventions);

const libConfig = TypeScriptBestPractices.createTSConfig('library', {
  outDir: './lib',
  declarationDir: './types'
});

console.log('库TS配置:', JSON.stringify(libConfig, null, 2));

总结

TypeScript通过强大的类型系统、接口泛型、装饰器等特性,极大地提升了JavaScript代码的质量和开发体验。本文深入探讨了TypeScript的核心实现原理和高级特性,并提供了实际可用的代码示例。

核心要点总结:

  1. 类型系统: TypeScript通过编译时类型检查提供安全保障,运行时也可通过代理模式实现类型验证
  2. 接口与泛型: 通过设计模式模拟接口实现,泛型提供代码复用性和类型安全性
  3. 装饰器: 元编程的强大工具,实现依赖注入、验证、日志等横切关注点
  4. 类型推断: 自动推断变量类型,减少冗余的类型注解
  5. 模块与工程化: 完善的模块系统支持,与构建工具深度集成
  6. 最佳实践: 合理的项目结构、命名约定和错误处理策略

TypeScript不仅是JavaScript的类型超集,更是一种工程化实践。它将静态类型语言的严谨性与JavaScript的灵活性完美结合,成为现代前端开发不可或缺的工具。随着TypeScript的持续发展,其类型系统将变得更加智能和强大,为构建大型、可维护的应用程序提供坚实保障。

在实际项目中,应根据团队规模、项目复杂度和技术栈选择合适的TypeScript特性,平衡类型安全性和开发效率。通过渐进式迁移策略,即使现有JavaScript项目也能平滑过渡到TypeScript,享受类型系统带来的诸多好处。

工程化工具类:模块化系统全解析与实践

引言

在前端开发的演进历程中,模块化一直是工程化实践的核心。从早期的脚本标签堆砌到现代的ES Modules,模块化技术极大地提升了代码的可维护性、复用性和协作效率。本文将深入探讨模块化的各个方面,包括模块加载器实现、规范演化、Polyfill技术,并补充构建工具、性能优化等工程化实践,全面解析模块化在现代前端开发中的应用。

一、实现简单的模块加载器

在理解复杂模块系统之前,我们先实现一个简单的模块加载器,了解其核心原理。

1.1 基础模块加载器实现
// 简单的模块注册表
const moduleRegistry = {};
const moduleCache = {};

// 模块定义函数
function define(name, dependencies, factory) {
  if (!moduleRegistry[name]) {
    moduleRegistry[name] = {
      dependencies,
      factory,
      resolved: false,
      exports: null
    };
  }
}

// 模块加载函数
function require(name) {
  // 检查缓存
  if (moduleCache[name]) {
    return moduleCache[name];
  }
  
  const module = moduleRegistry[name];
  if (!module) {
    throw new Error(`Module ${name} not found`);
  }
  
  // 解析依赖
  const resolvedDeps = module.dependencies.map(dep => {
    if (dep === 'exports' || dep === 'module') {
      return null; // 特殊处理
    }
    return require(dep);
  });
  
  // 执行工厂函数获取模块导出
  const factoryResult = module.factory.apply(null, resolvedDeps);
  
  // 缓存模块导出
  moduleCache[name] = factoryResult || {};
  module.resolved = true;
  
  return moduleCache[name];
}

// 使用示例
define('math', [], function() {
  return {
    add: (a, b) => a + b,
    multiply: (a, b) => a * b
  };
});

define('calculator', ['math'], function(math) {
  return {
    calculate: (x, y) => math.multiply(math.add(x, y), 2)
  };
});

// 使用模块
const calculator = require('calculator');
console.log(calculator.calculate(2, 3)); // 10
1.2 异步模块加载器
class AsyncModuleLoader {
  constructor() {
    this.modules = new Map();
    this.loading = new Map();
  }
  
  // 定义模块
  define(name, deps, factory) {
    this.modules.set(name, {
      deps,
      factory,
      exports: null,
      resolved: false
    });
  }
  
  // 异步加载模块
  async require(name) {
    if (this.modules.get(name)?.resolved) {
      return this.modules.get(name).exports;
    }
    
    // 防止重复加载
    if (this.loading.has(name)) {
      return this.loading.get(name);
    }
    
    // 创建加载Promise
    const loadPromise = this._loadModule(name);
    this.loading.set(name, loadPromise);
    
    return loadPromise;
  }
  
  async _loadModule(name) {
    const module = this.modules.get(name);
    if (!module) {
      throw new Error(`Module ${name} not found`);
    }
    
    // 加载所有依赖
    const depPromises = module.deps.map(dep => this.require(dep));
    const deps = await Promise.all(depPromises);
    
    // 执行工厂函数
    const exports = module.factory.apply(null, deps);
    
    // 更新模块状态
    module.exports = exports || {};
    module.resolved = true;
    this.loading.delete(name);
    
    return module.exports;
  }
}

// 使用示例
const loader = new AsyncModuleLoader();

loader.define('utils', [], () => ({
  format: str => str.toUpperCase()
}));

loader.define('app', ['utils'], (utils) => {
  return {
    run: () => console.log(utils.format('hello'))
  };
});

loader.require('app').then(app => app.run()); // 输出: HELLO

二、AMD规范实现

AMD(Asynchronous Module Definition)规范是RequireJS推广的异步模块定义标准。

2.1 简化的AMD实现
(function(global) {
  // 模块缓存
  const modules = {};
  const inProgress = {};
  
  // 定义函数
  function define(id, dependencies, factory) {
    if (arguments.length === 2) {
      factory = dependencies;
      dependencies = [];
    }
    
    modules[id] = {
      id: id,
      dependencies: dependencies,
      factory: factory,
      exports: null,
      resolved: false
    };
    
    // 尝试解析模块
    resolveModule(id);
  }
  
  // 依赖解析
  function resolveModule(id) {
    const module = modules[id];
    if (!module || module.resolved) return;
    
    // 检查依赖是否都可用
    const deps = module.dependencies;
    const missingDeps = deps.filter(dep => 
      !modules[dep] || !modules[dep].resolved
    );
    
    if (missingDeps.length === 0) {
      // 所有依赖已就绪,执行工厂函数
      executeModule(id);
    } else {
      // 等待依赖
      missingDeps.forEach(dep => {
        if (!inProgress[dep]) {
          inProgress[dep] = [];
        }
        inProgress[dep].push(id);
      });
    }
  }
  
  // 执行模块
  function executeModule(id) {
    const module = modules[id];
    if (module.resolved) return;
    
    // 获取依赖的exports
    const depExports = module.dependencies.map(dep => {
      if (dep === 'exports') return {};
      if (dep === 'require') return createRequire();
      if (dep === 'module') return { id: module.id, exports: {} };
      return modules[dep].exports;
    });
    
    // 执行工厂函数
    const exports = module.factory.apply(null, depExports);
    
    // 设置exports
    module.exports = exports || 
      (depExports[module.dependencies.indexOf('exports')] || {});
    module.resolved = true;
    
    // 通知等待此模块的其他模块
    if (inProgress[id]) {
      inProgress[id].forEach(dependentId => resolveModule(dependentId));
      delete inProgress[id];
    }
  }
  
  // 创建require函数
  function createRequire() {
    return function(ids, callback) {
      if (typeof ids === 'string') ids = [ids];
      
      Promise.all(ids.map(loadModule))
        .then(modules => {
          if (callback) callback.apply(null, modules);
        });
    };
  }
  
  // 异步加载模块
  function loadModule(id) {
    return new Promise((resolve, reject) => {
      if (modules[id] && modules[id].resolved) {
        resolve(modules[id].exports);
        return;
      }
      
      // 动态加载脚本
      const script = document.createElement('script');
      script.src = id + '.js';
      script.onload = () => {
        // 等待模块解析
        const checkInterval = setInterval(() => {
          if (modules[id] && modules[id].resolved) {
            clearInterval(checkInterval);
            resolve(modules[id].exports);
          }
        }, 10);
      };
      script.onerror = reject;
      document.head.appendChild(script);
    });
  }
  
  // 暴露到全局
  global.define = define;
  global.require = createRequire();
  
})(typeof window !== 'undefined' ? window : global);

// 使用示例
define('math', [], function() {
  return {
    add: function(a, b) { return a + b; }
  };
});

define('app', ['math', 'require'], function(math, require) {
  return {
    calculate: function() {
      return math.add(1, 2);
    },
    loadExtra: function() {
      require(['utils'], function(utils) {
        console.log('Utils loaded');
      });
    }
  };
});

require(['app'], function(app) {
  console.log(app.calculate()); // 3
});

三、CMD规范实现

CMD(Common Module Definition)规范由Sea.js推广,强调就近依赖。

3.1 简化的CMD实现
(function(global) {
  const modules = {};
  const factories = {};
  const cache = {};
  
  // 模块状态
  const STATUS = {
    PENDING: 0,
    LOADING: 1,
    LOADED: 2,
    EXECUTING: 3,
    EXECUTED: 4
  };
  
  // 定义函数
  function define(factory) {
    // 获取当前脚本
    const scripts = document.getElementsByTagName('script');
    const currentScript = scripts[scripts.length - 1];
    const id = currentScript.src.replace(/\.js$/, '');
    
    factories[id] = factory;
    modules[id] = {
      id: id,
      factory: factory,
      deps: [],
      exports: null,
      status: STATUS.PENDING,
      callbacks: []
    };
    
    // 解析依赖
    parseDependencies(id);
  }
  
  // 解析依赖
  function parseDependencies(id) {
    const factory = factories[id];
    if (!factory) return;
    
    const source = factory.toString();
    const requireRegex = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
    const deps = [];
    let match;
    
    while ((match = requireRegex.exec(source)) !== null) {
      deps.push(match[1]);
    }
    
    modules[id].deps = deps;
  }
  
  // 异步加载模块
  function require(id, callback) {
    const module = modules[id];
    
    if (module && module.status === STATUS.EXECUTED) {
      // 模块已执行,直接返回
      if (callback) {
        callback(module.exports);
      }
      return module.exports;
    }
    
    // 模块未加载,开始加载
    if (!module || module.status === STATUS.PENDING) {
      return loadModule(id, callback);
    }
    
    // 模块加载中,添加回调
    if (module.status < STATUS.EXECUTED) {
      module.callbacks.push(callback);
    }
  }
  
  // 加载模块
  function loadModule(id, callback) {
    const module = modules[id] || (modules[id] = {
      id: id,
      deps: [],
      exports: null,
      status: STATUS.LOADING,
      callbacks: callback ? [callback] : []
    });
    
    // 创建script标签加载
    const script = document.createElement('script');
    script.src = id + '.js';
    script.async = true;
    
    script.onload = function() {
      module.status = STATUS.LOADED;
      executeModule(id);
    };
    
    script.onerror = function() {
      console.error(`Failed to load module: ${id}`);
    };
    
    document.head.appendChild(script);
    
    return null;
  }
  
  // 执行模块
  function executeModule(id) {
    const module = modules[id];
    if (!module || module.status >= STATUS.EXECUTING) return;
    
    module.status = STATUS.EXECUTING;
    
    // 收集依赖
    const deps = module.deps;
    const depValues = deps.map(depId => {
      const depModule = modules[depId];
      if (depModule && depModule.status === STATUS.EXECUTED) {
        return depModule.exports;
      }
      // 同步加载依赖(简化实现)
      return require(depId);
    });
    
    // 执行工厂函数
    const factory = factories[id];
    if (!factory) {
      throw new Error(`Factory not found for module: ${id}`);
    }
    
    // 提供require、exports、module参数
    const localRequire = function(depId) {
      return require(depId);
    };
    
    const localExports = {};
    const localModule = { exports: localExports };
    
    // 执行
    const result = factory.call(null, localRequire, localExports, localModule);
    
    // 设置exports
    module.exports = localModule.exports || result || localExports;
    module.status = STATUS.EXECUTED;
    
    // 执行回调
    module.callbacks.forEach(cb => cb(module.exports));
    module.callbacks = [];
  }
  
  // 暴露全局
  global.define = define;
  global.require = require;
  
})(typeof window !== 'undefined' ? window : global);

// 使用示例
// 文件: math.js
define(function(require, exports, module) {
  module.exports = {
    add: function(a, b) {
      return a + b;
    }
  };
});

// 文件: app.js
define(function(require, exports, module) {
  var math = require('math');
  
  exports.calculate = function() {
    return math.add(1, 2);
  };
});

// 主文件
require('app', function(app) {
  console.log(app.calculate()); // 3
});

四、ES Module的简单Polyfill

虽然现代浏览器支持ES Modules,但在某些场景下,我们仍需要Polyfill支持。

4.1 基础ESM Polyfill实现
// ES Module Polyfill
(function() {
  const moduleMap = new Map();
  const moduleCache = new Map();
  
  // 拦截import语句(通过动态import实现)
  window.importModule = async function(modulePath) {
    // 检查缓存
    if (moduleCache.has(modulePath)) {
      return moduleCache.get(modulePath);
    }
    
    // 加载模块代码
    const code = await fetchModule(modulePath);
    
    // 解析依赖
    const deps = extractDependencies(code);
    
    // 加载依赖
    const depPromises = deps.map(dep => 
      importModule(resolvePath(modulePath, dep))
    );
    const dependencies = await Promise.all(depPromises);
    
    // 执行模块
    const moduleExports = {};
    const module = {
      exports: moduleExports
    };
    
    // 创建包装函数
    const wrapper = createWrapper(code, dependencies);
    wrapper(
      moduleExports, // exports
      module,        // module
      modulePath     // __filename(模拟)
    );
    
    // 缓存结果
    const exports = module.exports === moduleExports ? 
      moduleExports : module.exports;
    moduleCache.set(modulePath, exports);
    
    return exports;
  };
  
  // 提取依赖
  function extractDependencies(code) {
    const importRegex = /import\s+.*?\s+from\s+['"](.*?)['"]/g;
    const dynamicImportRegex = /import\s*\(['"](.*?)['"]\)/g;
    const deps = new Set();
    
    let match;
    while ((match = importRegex.exec(code)) !== null) {
      deps.add(match[1]);
    }
    
    // 重置正则
    importRegex.lastIndex = 0;
    
    while ((match = dynamicImportRegex.exec(code)) !== null) {
      deps.add(match[1]);
    }
    
    return Array.from(deps);
  }
  
  // 创建包装函数
  function createWrapper(code, dependencies) {
    const wrapperCode = `
      (function(exports, module, __filename, __dirname) {
        // 注入依赖
        const [
          ${dependencies.map((_, i) => `__dep${i}`).join(', ')}
        ] = arguments[4];
        
        ${code}
        
        // 返回默认导出
        return module.exports && module.exports.default ?
          module.exports.default : module.exports;
      })
    `;
    
    return eval(wrapperCode);
  }
  
  // 解析路径
  function resolvePath(basePath, targetPath) {
    if (targetPath.startsWith('./') || targetPath.startsWith('../')) {
      const baseDir = basePath.substring(0, basePath.lastIndexOf('/'));
      return new URL(targetPath, baseDir + '/').pathname;
    }
    return targetPath;
  }
  
  // 获取模块代码
  async function fetchModule(path) {
    const response = await fetch(path);
    if (!response.ok) {
      throw new Error(`Failed to load module: ${path}`);
    }
    return response.text();
  }
  
  // 拦截script type="module"
  interceptModuleScripts();
  
  function interceptModuleScripts() {
    const originalCreateElement = document.createElement;
    
    document.createElement = function(tagName) {
      const element = originalCreateElement.call(document, tagName);
      
      if (tagName === 'script') {
        const originalSetAttribute = element.setAttribute.bind(element);
        
        element.setAttribute = function(name, value) {
          originalSetAttribute(name, value);
          
          if (name === 'type' && value === 'module') {
            // 拦截模块脚本
            const src = element.getAttribute('src');
            if (src) {
              element.type = 'text/javascript';
              importModule(src).then(() => {
                if (element.onload) element.onload();
              }).catch(err => {
                if (element.onerror) element.onerror(err);
              });
            }
          }
        };
      }
      
      return element;
    };
  }
})();

// 使用示例
// 模块文件: utils.js
export function capitalize(str) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}

export default function greet(name) {
  return `Hello, ${capitalize(name)}!`;
}

// 主文件
importModule('./utils.js').then(utils => {
  console.log(utils.default('world')); // Hello, World!
  console.log(utils.capitalize('test')); // Test
});
4.2 支持Tree Shaking的ESM Polyfill
class ESMCompat {
  constructor() {
    this.modules = new Map();
    this.usedExports = new Set();
  }
  
  // 注册模块
  register(name, code) {
    const ast = this.parse(code);
    const exports = this.extractExports(ast);
    
    this.modules.set(name, {
      code,
      ast,
      exports,
      used: new Set()
    });
  }
  
  // 解析代码为AST(简化版)
  parse(code) {
    // 简化实现:实际应使用Babel等解析器
    const exportMatches = code.match(/export\s+(const|let|var|function|class|default)\s+(\w+)/g) || [];
    const imports = code.match(/import\s+\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]/g) || [];
    
    return {
      exports: exportMatches.map(match => ({
        type: match.split(' ')[1],
        name: match.split(' ')[2]
      })),
      imports: imports.map(match => {
        const parts = match.match(/import\s+\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]/);
        return {
          specifiers: parts[1].split(',').map(s => s.trim()),
          source: parts[2]
        };
      })
    };
  }
  
  // 提取导出
  extractExports(ast) {
    return ast.exports.map(exp => exp.name);
  }
  
  // 使用模块(标记使用的导出)
  use(name, ...exports) {
    const module = this.modules.get(name);
    if (module) {
      exports.forEach(exp => {
        if (module.exports.includes(exp)) {
          module.used.add(exp);
        }
      });
    }
  }
  
  // 生成优化后的代码
  generateOptimized(name) {
    const module = this.modules.get(name);
    if (!module) return '';
    
    let code = module.code;
    
    // 移除未使用的导出(简化实现)
    module.exports.forEach(exp => {
      if (!module.used.has(exp)) {
        const regex = new RegExp(`export\\s+.*?\\b${exp}\\b[^;]*;`, 'g');
        code = code.replace(regex, '');
      }
    });
    
    return code;
  }
}

// 使用示例
const compat = new ESMCompat();

compat.register('math', `
export const PI = 3.14159;
export function add(a, b) { return a + b; }
export function multiply(a, b) { return a * b; }
export function unusedFunction() { return 'unused'; }
`);

// 标记使用的导出
compat.use('math', 'PI', 'add');

// 生成优化代码
console.log(compat.generateOptimized('math'));
// 输出将只包含PI和add的导出

五、模块化构建工具集成

现代开发中,我们使用构建工具处理模块化。以下展示如何集成Webpack-like的简单打包器。

5.1 简易模块打包器
const fs = require('fs');
const path = require('path');
const { parse } = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const generate = require('@babel/generator').default;
const t = require('@babel/types');

class SimpleBundler {
  constructor(entry) {
    this.entry = entry;
    this.modules = new Map();
    this.moduleId = 0;
  }
  
  // 构建
  build(outputPath) {
    const entryModule = this.collectDependencies(this.entry);
    const bundleCode = this.generateBundle(entryModule);
    
    fs.writeFileSync(outputPath, bundleCode);
    console.log(`Bundle generated: ${outputPath}`);
  }
  
  // 收集依赖
  collectDependencies(filePath) {
    const fileContent = fs.readFileSync(filePath, 'utf-8');
    const ast = parse(fileContent, {
      sourceType: 'module',
      plugins: ['jsx']
    });
    
    const dependencies = [];
    const dirname = path.dirname(filePath);
    
    // 遍历AST收集import语句
    traverse(ast, {
      ImportDeclaration: ({ node }) => {
        const importPath = node.source.value;
        const absolutePath = this.resolvePath(importPath, dirname);
        dependencies.push(absolutePath);
      },
      CallExpression: ({ node }) => {
        if (node.callee.type === 'Import') {
          const importPath = node.arguments[0].value;
          const absolutePath = this.resolvePath(importPath, dirname);
          dependencies.push(absolutePath);
        }
      }
    });
    
    const moduleId = this.moduleId++;
    const module = {
      id: moduleId,
      filePath,
      code: fileContent,
      dependencies,
      mapping: {}
    };
    
    this.modules.set(filePath, module);
    
    // 递归收集依赖
    dependencies.forEach(dep => {
      if (!this.modules.has(dep)) {
        this.collectDependencies(dep);
      }
    });
    
    return module;
  }
  
  // 解析路径
  resolvePath(importPath, baseDir) {
    if (importPath.startsWith('.')) {
      return path.resolve(baseDir, importPath);
    }
    // 处理node_modules(简化)
    const nodeModulePath = path.resolve(process.cwd(), 'node_modules', importPath);
    if (fs.existsSync(nodeModulePath)) {
      return nodeModulePath;
    }
    return importPath;
  }
  
  // 生成打包代码
  generateBundle(entryModule) {
    const modules = [];
    
    // 创建模块映射
    this.modules.forEach(module => {
      const transformedCode = this.transformModule(module);
      modules.push(`
        ${module.id}: {
          factory: function(require, module, exports) {
            ${transformedCode}
          },
          mapping: ${JSON.stringify(module.mapping)}
        }
      `);
    });
    
    // 生成运行时
    return `
      (function(modules) {
        const moduleCache = {};
        
        function require(id) {
          if (moduleCache[id]) {
            return moduleCache[id].exports;
          }
          
          const mod = modules[id];
          const localRequire = function(modulePath) {
            return require(mod.mapping[modulePath]);
          };
          
          const module = { exports: {} };
          mod.factory(localRequire, module, module.exports);
          
          moduleCache[id] = module;
          return module.exports;
        }
        
        // 启动入口模块
        require(0);
      })({
        ${modules.join(',\n')}
      });
    `;
  }
  
  // 转换模块代码
  transformModule(module) {
    const ast = parse(module.code, {
      sourceType: 'module'
    });
    
    // 构建路径映射
    let importIndex = 0;
    
    traverse(ast, {
      ImportDeclaration: ({ node }) => {
        const importPath = node.source.value;
        const depModule = this.modules.get(
          this.resolvePath(importPath, path.dirname(module.filePath))
        );
        
        if (depModule) {
          const importName = `__import_${importIndex++}`;
          module.mapping[importPath] = depModule.id;
          
          // 替换import语句
          const specifiers = node.specifiers.map(spec => {
            if (t.isImportDefaultSpecifier(spec)) {
              return t.variableDeclarator(
                spec.local,
                t.memberExpression(
                  t.identifier(importName),
                  t.identifier('default')
                )
              );
            } else {
              return t.variableDeclarator(
                spec.local,
                t.memberExpression(
                  t.identifier(importName),
                  spec.imported || spec.local
                )
              );
            }
          });
          
          return t.variableDeclaration('const', specifiers);
        }
      }
    });
    
    // 移除export语句
    traverse(ast, {
      ExportNamedDeclaration: ({ node, remove }) => {
        if (node.declaration) {
          return node.declaration;
        }
        remove();
      },
      ExportDefaultDeclaration: ({ node }) => {
        return t.expressionStatement(
          t.assignmentExpression(
            '=',
            t.memberExpression(
              t.identifier('module'),
              t.identifier('exports')
            ),
            t.objectExpression([
              t.objectProperty(
                t.identifier('default'),
                node.declaration
              )
            ])
          )
        );
      }
    });
    
    const { code } = generate(ast);
    return code;
  }
}

// 使用示例
const bundler = new SimpleBundler('./src/index.js');
bundler.build('./dist/bundle.js');

六、模块联邦与微前端架构

模块联邦(Module Federation)是Webpack 5引入的重要特性,支持跨应用共享模块。

6.1 简易模块联邦实现
// 模块联邦管理器
class ModuleFederation {
  constructor(config) {
    this.config = config;
    this.remotes = new Map();
    this.exposes = new Map();
    this.shared = new Map();
    this.init();
  }
  
  init() {
    // 初始化共享模块
    if (this.config.shared) {
      Object.entries(this.config.shared).forEach(([name, config]) => {
        this.shared.set(name, {
          module: require(name),
          version: config.version,
          singleton: config.singleton || false
        });
      });
    }
    
    // 初始化暴露模块
    if (this.config.exposes) {
      Object.entries(this.config.exposes).forEach(([name, modulePath]) => {
        this.exposes.set(name, require(modulePath));
      });
    }
  }
  
  // 注册远程应用
  async registerRemote(name, url) {
    try {
      const remoteManifest = await this.fetchRemoteManifest(url);
      this.remotes.set(name, {
        url,
        manifest: remoteManifest
      });
      console.log(`Remote ${name} registered`);
    } catch (error) {
      console.error(`Failed to register remote ${name}:`, error);
    }
  }
  
  // 获取远程清单
  async fetchRemoteManifest(url) {
    const response = await fetch(`${url}/federation-manifest.json`);
    return response.json();
  }
  
  // 获取模块
  async getModule(remoteName, moduleName) {
    // 检查共享模块
    if (this.shared.has(moduleName)) {
      return this.shared.get(moduleName).module;
    }
    
    // 检查本地暴露
    if (this.exposes.has(moduleName)) {
      return this.exposes.get(moduleName);
    }
    
    // 检查远程模块
    const remote = this.remotes.get(remoteName);
    if (remote) {
      return this.loadRemoteModule(remote, moduleName);
    }
    
    throw new Error(`Module ${moduleName} not found`);
  }
  
  // 加载远程模块
  async loadRemoteModule(remote, moduleName) {
    const moduleUrl = `${remote.url}/${moduleName}.js`;
    
    // 动态加载脚本
    return new Promise((resolve, reject) => {
      const script = document.createElement('script');
      script.src = moduleUrl;
      
      script.onload = () => {
        // 假设远程模块会暴露到全局
        const module = window[`${remote.name}_${moduleName}`];
        if (module) {
          resolve(module);
        } else {
          reject(new Error(`Module ${moduleName} not found in remote`));
        }
      };
      
      script.onerror = reject;
      document.head.appendChild(script);
    });
  }
  
  // 暴露模块
  expose(name, module) {
    this.exposes.set(name, module);
    // 暴露到全局(供远程访问)
    window[`${this.config.name}_${name}`] = module;
  }
}

// 使用示例
// App 1 配置
const federation1 = new ModuleFederation({
  name: 'app1',
  exposes: {
    './Button': './src/components/Button.js'
  },
  shared: {
    react: { singleton: true, version: '17.0.0' },
    'react-dom': { singleton: true, version: '17.0.0' }
  }
});

// App 2 配置
const federation2 = new ModuleFederation({
  name: 'app2',
  remotes: {
    app1: 'http://localhost:3001'
  },
  shared: {
    react: { singleton: true, version: '17.0.0' }
  }
});

// App2中使用App1的模块
federation2.getModule('app1', 'Button').then(Button => {
  // 使用远程Button组件
  console.log('Remote Button loaded:', Button);
});
七、模块化性能优化
7.1 代码分割与懒加载
class CodeSplitter {
  constructor() {
    this.chunks = new Map();
    this.loadedChunks = new Set();
  }
  
  // 定义代码分割点
  defineChunk(name, getChunk) {
    this.chunks.set(name, getChunk);
  }
  
  // 懒加载代码块
  async loadChunk(name) {
    if (this.loadedChunks.has(name)) {
      return;
    }
    
    const getChunk = this.chunks.get(name);
    if (!getChunk) {
      throw new Error(`Chunk ${name} not found`);
    }
    
    // 标记为加载中
    this.loadedChunks.add(name);
    
    try {
      await getChunk();
      console.log(`Chunk ${name} loaded`);
    } catch (error) {
      this.loadedChunks.delete(name);
      throw error;
    }
  }
  
  // 预加载代码块
  preloadChunk(name) {
    if (this.loadedChunks.has(name)) return;
    
    const link = document.createElement('link');
    link.rel = 'preload';
    link.as = 'script';
    
    const getChunk = this.chunks.get(name);
    if (getChunk && getChunk.chunkPath) {
      link.href = getChunk.chunkPath;
      document.head.appendChild(link);
    }
  }
}

// Webpack动态导入兼容
function dynamicImport(modulePath) {
  if (typeof __webpack_require__ !== 'undefined') {
    // Webpack环境
    return import(/* webpackChunkName: "[request]" */ modulePath);
  } else {
    // 原生环境
    return import(modulePath);
  }
}

// 使用示例
const splitter = new CodeSplitter();

// 定义代码块
splitter.defineChunk('dashboard', () => 
  dynamicImport('./Dashboard.js')
);

splitter.defineChunk('analytics', () => 
  dynamicImport('./Analytics.js')
);

// 路由懒加载
async function loadRoute(routeName) {
  switch (routeName) {
    case 'dashboard':
      await splitter.loadChunk('dashboard');
      break;
    case 'analytics':
      await splitter.loadChunk('analytics');
      break;
  }
}

// 预加载
window.addEventListener('mouseover', (e) => {
  if (e.target.href && e.target.href.includes('dashboard')) {
    splitter.preloadChunk('dashboard');
  }
});
7.2 模块缓存策略
class ModuleCache {
  constructor() {
    this.cache = new Map();
    this.ttl = 5 * 60 * 1000; // 5分钟
    this.maxSize = 100; // 最大缓存模块数
  }
  
  // 获取模块
  async get(key, fetchModule) {
    const cached = this.cache.get(key);
    
    // 检查缓存是否有效
    if (cached && Date.now() - cached.timestamp < this.ttl) {
      console.log(`Cache hit: ${key}`);
      return cached.module;
    }
    
    // 缓存失效或不存在,重新获取
    console.log(`Cache miss: ${key}`);
    const module = await fetchModule();
    
    // 更新缓存
    this.set(key, module);
    
    return module;
  }
  
  // 设置缓存
  set(key, module) {
    // 清理过期缓存
    this.cleanup();
    
    this.cache.set(key, {
      module,
      timestamp: Date.now()
    });
  }
  
  // 清理缓存
  cleanup() {
    const now = Date.now();
    
    // 清理过期
    for (const [key, value] of this.cache) {
      if (now - value.timestamp > this.ttl) {
        this.cache.delete(key);
      }
    }
    
    // 清理超出大小限制的(LRU策略)
    if (this.cache.size > this.maxSize) {
      const entries = Array.from(this.cache.entries());
      entries.sort((a, b) => a[1].timestamp - b[1].timestamp);
      
      for (let i = 0; i < entries.length - this.maxSize; i++) {
        this.cache.delete(entries[i][0]);
      }
    }
  }
  
  // 清空缓存
  clear() {
    this.cache.clear();
  }
}

// 使用示例
const moduleCache = new ModuleCache();

async function loadModuleWithCache(modulePath) {
  return moduleCache.get(modulePath, async () => {
    const response = await fetch(modulePath);
    return response.text();
  });
}

八、模块化最佳实践与工程化

8.1 模块设计原则
// 1. 单一职责原则
// 不好的例子
class UserManager {
  // 混合了用户管理、验证、通知等多个职责
}

// 好的例子
class UserRepository {
  // 只负责数据访问
}

class UserValidator {
  // 只负责验证
}

class UserNotifier {
  // 只负责通知
}

// 2. 依赖注入
class UserService {
  constructor(userRepository, validator, notifier) {
    this.userRepository = userRepository;
    this.validator = validator;
    this.notifier = notifier;
  }
  
  async register(user) {
    if (!this.validator.validate(user)) {
      throw new Error('Invalid user');
    }
    
    await this.userRepository.save(user);
    await this.notifier.sendWelcome(user.email);
  }
}

// 3. 接口抽象
// 定义接口
class IStorage {
  async save(key, value) {}
  async get(key) {}
  async delete(key) {}
}

// 具体实现
class LocalStorage extends IStorage {
  async save(key, value) {
    localStorage.setItem(key, JSON.stringify(value));
  }
  
  async get(key) {
    return JSON.parse(localStorage.getItem(key));
  }
  
  async delete(key) {
    localStorage.removeItem(key);
  }
}

class APIService {
  constructor(storage) {
    if (!(storage instanceof IStorage)) {
      throw new Error('Invalid storage implementation');
    }
    this.storage = storage;
  }
}
8.2 模块版本管理与升级
class ModuleVersionManager {
  constructor() {
    this.versions = new Map();
    this.deprecations = new Map();
  }
  
  // 注册模块版本
  register(moduleName, version, module) {
    if (!this.versions.has(moduleName)) {
      this.versions.set(moduleName, new Map());
    }
    
    this.versions.get(moduleName).set(version, module);
  }
  
  // 获取模块(支持语义化版本)
  get(moduleName, versionRange = 'latest') {
    const moduleVersions = this.versions.get(moduleName);
    if (!moduleVersions) {
      throw new Error(`Module ${moduleName} not found`);
    }
    
    if (versionRange === 'latest') {
      const latestVersion = Array.from(moduleVersions.keys())
        .sort(this.compareVersions)
        .pop();
      return moduleVersions.get(latestVersion);
    }
    
    // 简化的版本范围解析
    const availableVersions = Array.from(moduleVersions.keys())
      .filter(v => this.satisfiesVersion(v, versionRange))
      .sort(this.compareVersions);
    
    if (availableVersions.length === 0) {
      throw new Error(`No version of ${moduleName} satisfies ${versionRange}`);
    }
    
    return moduleVersions.get(availableVersions.pop());
  }
  
  // 比较版本
  compareVersions(v1, v2) {
    const parts1 = v1.split('.').map(Number);
    const parts2 = v2.split('.').map(Number);
    
    for (let i = 0; i < 3; i++) {
      if (parts1[i] !== parts2[i]) {
        return parts1[i] - parts2[i];
      }
    }
    
    return 0;
  }
  
  // 检查版本是否满足范围
  satisfiesVersion(version, range) {
    // 简化实现,实际应使用semver库
    if (range === '*') return true;
    
    const [op, versionRange] = range.match(/^([>=<~^]*)(\d+\.\d+\.\d+)$/).slice(1);
    const vParts = version.split('.').map(Number);
    const rParts = versionRange.split('.').map(Number);
    
    switch (op) {
      case '^': // 兼容版本
        return vParts[0] === rParts[0] && vParts[1] >= rParts[1];
      case '~': // 近似版本
        return vParts[0] === rParts[0] && 
               vParts[1] === rParts[1] && 
               vParts[2] >= rParts[2];
      case '>=':
        return this.compareVersions(version, versionRange) >= 0;
      case '>':
        return this.compareVersions(version, versionRange) > 0;
      case '<=':
        return this.compareVersions(version, versionRange) <= 0;
      case '<':
        return this.compareVersions(version, versionRange) < 0;
      default:
        return version === versionRange;
    }
  }
  
  // 弃用通知
  deprecate(moduleName, version, message) {
    if (!this.deprecations.has(moduleName)) {
      this.deprecations.set(moduleName, new Map());
    }
    
    this.deprecations.get(moduleName).set(version, {
      message,
      deprecatedAt: new Date()
    });
    
    // 添加控制台警告
    console.warn(`Module ${moduleName}@${version} is deprecated: ${message}`);
  }
}

// 使用示例
const versionManager = new ModuleVersionManager();

// 注册不同版本
versionManager.register('utils', '1.0.0', {
  oldMethod: () => 'old'
});

versionManager.register('utils', '1.1.0', {
  oldMethod: () => 'old',
  newMethod: () => 'new'
});

versionManager.register('utils', '2.0.0', {
  newMethod: () => 'new',
  betterMethod: () => 'better'
});

// 标记弃用
versionManager.deprecate('utils', '1.0.0', '请升级到1.1.0+版本');

// 获取模块
const utilsV1 = versionManager.get('utils', '^1.0.0');
console.log(utilsV1); // 1.1.0版本

const utilsLatest = versionManager.get('utils');
console.log(utilsLatest); // 2.0.0版本

总结

模块化是现代前端工程化的基石,从前端的脚本标签到ES Modules,再到模块联邦等高级模式,模块化技术不断演进。本文从简单模块加载器实现开始,逐步深入AMD、CMD规范,探讨ES Module的Polyfill技术,并补充了构建工具集成、模块联邦、性能优化等工程化实践。

关键要点总结:

  1. 模块加载器核心原理: 依赖管理、缓存、异步加载
  2. 规范演进: 从AMD/CMD到ES Modules的统一
  3. 工程化实践: 代码分割、懒加载、版本管理、依赖注入
  4. 未来趋势: 模块联邦、微前端架构、Web Assembly模块化

模块化不仅仅是技术选择,更是一种设计哲学。良好的模块化设计能够提升代码的可维护性、可测试性和团队协作效率。在实际项目中,应根据团队规模、项目复杂度和技术栈选择合适的模块化方案,并不断优化模块边界和依赖关系。

随着前端技术的不断发展,模块化将继续演进,但核心原则——关注点分离、接口抽象、依赖管理——将始终保持不变。掌握模块化的核心原理和实践,能够帮助开发者构建更健壮、可维护的前端应用。

❌