阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 外部扩展(Externals)配置

外部扩展(Externals)配置

作者:陈川 阅读数:11261人阅读 分类: 构建工具

什么是外部扩展(Externals)

Webpack的外部扩展(Externals)配置允许开发者从输出的bundle中排除某些依赖,这些依赖会在运行时(runtime)从外部获取。这种方式特别适合处理那些通过CDN引入的库,或者那些已经被其他方式引入到运行环境的依赖。

// webpack.config.js
module.exports = {
  externals: {
    jquery: 'jQuery'
  }
};

外部扩展的基本用法

配置externals最常见的方式是使用对象语法。键(key)表示要排除的模块名称,值(value)表示在运行时应该使用的全局变量。

externals: {
  lodash: '_',
  react: 'React',
  'react-dom': 'ReactDOM'
}

当代码中require或import这些模块时,webpack不会将它们打包,而是保留为外部依赖:

import _ from 'lodash';  // 实际会使用全局的_变量

外部扩展的多种配置形式

字符串形式

最简单的形式是直接指定全局变量名:

externals: {
  jquery: 'jQuery'
}

数组形式

当需要同时指定模块名称和全局变量时:

externals: {
  subtract: ['./math', 'subtract']
}

对象形式

提供更细粒度的控制:

externals: {
  react: {
    root: 'React',
    commonjs: 'react',
    commonjs2: 'react',
    amd: 'react'
  }
}

函数形式

最灵活的方式,可以自定义处理逻辑:

externals: [
  function(context, request, callback) {
    if (/^yourregex$/.test(request)) {
      return callback(null, 'commonjs ' + request);
    }
    callback();
  }
]

不同模块系统中的外部扩展

CommonJS外部扩展

externals: {
  fs: 'commonjs fs',
  path: 'commonjs path'
}

AMD外部扩展

externals: {
  jquery: {
    amd: 'jQuery'
  }
}

UMD外部扩展

externals: {
  moment: {
    root: 'moment',
    commonjs: 'moment',
    commonjs2: 'moment',
    amd: 'moment'
  }
}

实际应用场景

排除CDN引入的库

<!-- index.html -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
// webpack.config.js
externals: {
  jquery: 'jQuery'
}

微前端架构中的共享依赖

在微前端架构中,主应用和子应用可以共享某些库:

// 子应用的webpack配置
externals: {
  react: 'react',
  'react-dom': 'reactDOM'
}

Node.js环境中的内置模块

构建Node.js应用时,可以排除内置模块:

externals: {
  fs: 'commonjs fs',
  path: 'commonjs path'
}

高级配置技巧

正则表达式匹配

externals: [
  /^[a-z\-0-9]+$/  // 排除所有符合该模式的模块
]

条件排除

externals: [
  function({ context, request }, callback) {
    if (request.includes('node_modules')) {
      return callback(null, `commonjs ${request}`);
    }
    callback();
  }
]

动态生成外部扩展

const nodeExternals = require('webpack-node-externals');

module.exports = {
  externals: [nodeExternals()],
  // 其他配置...
};

常见问题与解决方案

全局变量未定义错误

确保外部依赖确实在运行时可用:

externals: {
  jquery: {
    root: 'jQuery',
    commonjs: 'jquery',
    commonjs2: 'jquery',
    amd: 'jquery'
  }
}

与DLLPlugin的配合使用

externals: {
  'react': 'React',
  'react-dom': 'ReactDOM'
},
plugins: [
  new webpack.DllReferencePlugin({
    context: __dirname,
    manifest: require('./manifest.json')
  })
]

TypeScript中的类型定义

需要同时安装类型定义包:

npm install --save-dev @types/jquery

性能优化考虑

合理使用externals可以显著减少打包体积:

// 使用前
asset main.js 1.5 MiB [emitted] (name: main)

// 使用后
asset main.js 350 KiB [emitted] (name: main)

与其他配置的协同

与output.libraryTarget配合

output: {
  libraryTarget: 'umd'
},
externals: {
  react: 'react'
}

与SplitChunksPlugin的关系

externals配置的模块不会进入split chunks的优化流程。

测试与验证

验证externals配置是否生效:

// 打包后检查bundle
// 应该看不到被排除模块的代码

使用webpack-bundle-analyzer进行分析:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [new BundleAnalyzerPlugin()]
};

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌