GitLab执行nuxt generate报TypeError: external_defu_ is not a function
问题现象
在GitLab的Docker环境(Node版本v12.16.3)中为Nuxt项目执行generate构建命令时,每个待生成页面都会抛出如下异常,导致页面生成失败:
[error] /Dashboard TypeError: external_defu_ is not a function at server.js:12669:45 at Array.reduce (<anonymous>) at new runtime_BaseScheme (node_modules/@nuxtjs/auth-next/dist/runtime.mjs:883:0) at new runtime_Oauth2Scheme (node_modules/@nuxtjs/auth-next/dist/runtime.mjs:1137:0) at auth (node_modules/.cache/nuxt/auth.js:45:0) at createApp (node_modules/.cache/nuxt/index.js:291:0) at runNextTicks (node:internal/process/task_queues:61:5) at listOnTimeout (node:internal/timers/526:9) at processTimers (node:internal/timers/500:7) at async module.exports.__webpack_exports__.default (node_modules/.cache/nuxt/server.js:85:0)
相同Node版本下本地执行generate命令可正常完成所有页面生成,对应项目package.json配置如下:
{ "name": "xxx", "version": "1.0.0", "description": "xxx", "author": "Alessandro", "private": true, "scripts": { "generate": "ENV=production nuxt generate", generate", "lint": "eslint --ext .js,.vue --ignore-path .gitignore ." }, "dependencies": { "@nuxtjs/auth": "^4.9.1", "@nuxtjs/auth-next": "5.0.0-1613647907.37b1156", "@nuxtjs/axios": "^5.13.1", "@nuxtjs/pwa": "^3.3.4", "@vue/composition-api": "^0.6.7", "aws-sdk": "^2.610.0", "axios": "^0.21.1", "bcryptjs": "^2.4.3", "browser-image-compression": "^1.0.14", "caniuse-lite": "^1.0.30001257", "chart.js": "^2.9.3", "child_process": "^1.0.2", "compass": "^0.1.1", "cookie": "^0.4.0", "cookie-universal-nuxt": "^2.1.4", "cors": "^2.8.5", "cross-fetch": "^3.1.5", "file-saver": "^2.0.2", "fs": "0.0.1-security", "gapi-script": "^1.2.0", "install": "^0.13.0", "js-cookie": "^2.2.1", "kaleidoscopejs": "1.0.18", "leaflet": "^1.6.0", "lodash": "^4.17.15", "md5": "^2.2.1", "moment": "^2.29.3", "multer": "^1.4.2", "net": "^1.0.2", "node-fetch": "^2.6.7", "node-orientdb-http": "^0.1.1", "npm": "^8.13.1", "nuxt": "^2.15.0", "nuxt-gmaps": "^1.2.10", "nuxt-i18n": "^6.3.0", "nuxt-leaflet": "0.0.19", "nuxt-sass-resources-loader": "^2.0.5", "p-iteration": "^1.1.8", "pannellum": "github:saidmoya12/pannellum", "panolens": "^0.12.1", "proxy": "^1.0.2", "readline": "^1.3.0", "simple-analytics-vue": "^1.1.5", "tls": "0.0.1", "videojs": "^1.0.0", "videojs-panorama": "^0.1.7", "vue": "2.6.14", "vue-chartjs": "^3.5.0", "vue-cookie-accept-decline": "^5.3.1", "vue-expandable-image": "^0.1.0", "vue-google-login": "^2.0.3", "vue-pannellum": "^0.5.3", "vue-plausible": "^1.2.1", "vue-rangedate-picker": "^1.0.0", "vue-rangedate-picker-winslow": "^1.0.8", "vue-server-renderer": "^2.6.12", "vue-template-compiler": "^2.6.12", "vue-tooltipster": "^1.2.0", "vue-upload-multiple-image": "^1.1.4", "vue2-google-maps": "^0.10.7", "vue2-leaflet": "^2.6.0", "vuedraggable": "^2.23.2", "vuejs-panorama": "^1.1.9", "vuejs-vr": "^1.2.2", "vuetify": "^2.5.12", "vuex-persistedstate": "^3.0.1", "webpack": "^4.45.0" }, "devDependencies": { "@aceforth/nuxt-optimized-images": "^1.4.0", "@nuxt/bridge": "npm:@nuxt/bridge-edge@^3.0.0-27268729.5b8e10f", "@nuxt/image": "^0.7.1", "@nuxt/types": "^2.14.12", "@nuxtjs/dotenv": "^1.4.1", "@nuxtjs/eslint-config": "^3.1.0", "@nuxtjs/eslint-module": "^2.0.0", "@nuxtjs/google-analytics": "^2.4.0", "@nuxtjs/vuetify": "^1.12.3", "babel-eslint": "^10.0.1", "eslint": "^7.5.0", "eslint-plugin-nuxt": ">=0.4.2", "imagemin-gifsicle": "^7.0.0", "imagemin-mozjpeg": "^9.0.0", "imagemin-pngquant": "^9.0.2", "imagemin-svgo": "^9.0.0", "lqip-loader": "^2.2.1", "responsive-loader": "^2.3.0", "rimraf": "^3.0.2", "sharp": "^0.30.7", "sqip-loader": "^1.0.0", "webp-loader": "^0.6.0" } }
问题原因
报错核心是@nuxtjs/auth-next依赖的defu包版本不兼容:当前使用的@nuxtjs/auth-next版本以CommonJS规范引入defu,而6.x及以上版本的defu是纯ESM包,CJS方式引入时只会拿到模块对象而非默认导出函数,调用时就会抛出is not a function错误。
本地环境正常是因为本地依赖安装时拉取的是兼容版本的defu,GitLab CI环境如果没有按照锁文件安装依赖、或者缓存了异常版本的依赖,就会拉取到不兼容的高版本defu触发报错。另外当前package.json的scripts字段存在语法错误,也可能导致CI环境依赖解析异常。
解决方案
按优先级依次操作即可解决:
- 保证CI和本地依赖版本完全一致:将本地生成的
package-lock.json(或对应包管理器的锁文件)提交到Git仓库,CI脚本中使用npm ci代替npm install安装依赖,该命令会严格按照锁文件安装版本,不会自动升级符合semver范围的依赖。 - 手动固定defu的兼容版本:执行
npm install defu@5.0.1 -S安装兼容CJS调用的defu 5.x版本,该版本同时支持ESM和CJS引入,不会触发该报错,禁止升级到6.x及以上版本。 - 修正package.json的语法错误:删除scripts字段下孤立的
generate",行,修正后的scripts块如下:
"scripts": { "generate": "ENV=production nuxt generate", "lint": "eslint --ext .js,.vue --ignore-path .gitignore ." }
- 清理CI异常缓存:如果CI配置了node_modules缓存,先清空现有缓存再重新执行构建,避免旧的不兼容defu包被复用。
内容的提问来源于stack exchange,提问作者Alessandro M.
相关产品推荐
相关产品推荐

