解決使用 Gulp 發生 regeneratorRuntime is not defined 問題

前言

這一篇稍微記錄一下關於使用 gulp-babel 發生 regeneratorRuntime is not defined 的問題。

問題

六角學院這邊其實有提供一個 Gulp 範例,也就是「web-layout-training-gulp」這個儲存庫。

那麼這邊我們先試著製造一個會發生 regeneratorRuntime is not defined 的錯誤

1
2
3
4
5
6
// web-layout-training-gulp/app/assets/js/all.js
const test = async () => {
console.log('test');
};

test();

基本上當你運行 gulp 時就可以看到瀏覽器噴了 Uncaught ReferenceError: regeneratorRuntime is not defined 這個錯誤

regeneratorRuntime is not defined

那麼該怎麼解決呢?我們往下看。

解決方式

由於我們這邊 gulp 所使用的套件是 gulp-babel 因此官方文件上是有說明教你怎麼改的。

首先你必須先安裝以下套件

1
2
npm install --save-dev @babel/plugin-transform-runtime 
npm install --save @babel/runtime

接著打開 gulpfile.js/index.js,並找到 babel 的設定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// ... 略過

function babel() {
return gulp.src(envOptions.javascript.src)
.pipe($.sourcemaps.init())
.pipe($.babel({
presets: ['@babel/env'],
}))
.pipe($.concat(envOptions.javascript.concat))
.pipe($.sourcemaps.write('.'))
.pipe(gulp.dest(envOptions.javascript.path))
.pipe(
browserSync.reload({
stream: true,
}),
);
}

// ... 略過

接著將 .pipe($.babel({ presets: ['@babel/env'], })) 改掉,所以目前 babel 的設定應該會長這樣

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function babel() {
return gulp.src(envOptions.javascript.src)
.pipe($.sourcemaps.init())
.pipe($.babel({
plugins: ['@babel/transform-runtime']
}))
.pipe($.concat(envOptions.javascript.concat))
.pipe($.sourcemaps.write('.'))
.pipe(gulp.dest(envOptions.javascript.path))
.pipe(
browserSync.reload({
stream: true,
}),
);
}

那麼上方就是官方所提供的解決方式,但是如果你直接套用到 「web-layout-training-gulp」 這個儲存庫上,你會發現還是會發生其他錯誤。

因此接下來我將會一步一步分析解決這個問題

奇妙的 Uncaught SyntaxError

這邊所指的奇妙錯誤也就是 Uncaught SyntaxError: redeclaration of const Urladmin-member.js:46:4note: Previously declared at line 2, column 6 或是 Uncaught SyntaxError: Identifier 'Url' has already been declared

redeclaration

這個錯誤主要問題是因為我們把 presets: ['@babel/env'], 拔掉的關係,導致沒有辦法轉換 ES6 的語法,因此我們必須要再加上 presets: ['@babel/env'], 這個設定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function babel() {
return gulp.src(envOptions.javascript.src)
.pipe($.sourcemaps.init())
.pipe($.babel({
presets: ['@babel/env'],
plugins: ['@babel/transform-runtime']
}))
.pipe($.concat(envOptions.javascript.concat))
.pipe($.sourcemaps.write('.'))
.pipe(gulp.dest(envOptions.javascript.path))
.pipe(
browserSync.reload({
stream: true,
}),
);
}

詭異的 require is not defined

加回去後另一個更奇妙的問題又發生了,你會發現噴出了 Uncaught ReferenceError: require is not defined 這個錯誤。

Uncaught ReferenceError

那麼該怎麼解決呢?這邊讓我們看一下當前 package.json 中 babel 相關檔案的版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
// ...略過
"dependencies": {
"@babel/core": "^7.12.3",
"@babel/preset-env": "^7.12.1",
"@babel/runtime": "^7.20.1",
"autoprefixer": "^9.8.6",
"babel-polyfill": "^6.26.0",
"gulp-babel": "^8.0.0",
// ...略過
},
"devDependencies": {
"@babel/plugin-transform-runtime": "^7.19.6",
// ...略過
}
}

我們可以看到目前上方的 @babel/core@babel/preset-env 的版本是 7.12.37.12.1,而下方的 @babel/plugin-transform-runtime 的版本是 7.19.6,因此我們必須要將上方的版本都更新。

那麼為了更新乾脆一點,所以我們會連 gulp-babel 一起更新。

1
npm install --save-dev gulp-babel @babel/core @babel/preset-env

接著我們回到 gulpfile.js/index.js,將原本加上的 plugins: ['@babel/transform-runtime'] 移除改回原本的設定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function babel() {
return gulp.src(envOptions.javascript.src)
.pipe($.sourcemaps.init())
.pipe($.babel({
presets: ['@babel/env'],
}))
.pipe($.concat(envOptions.javascript.concat))
.pipe($.sourcemaps.write('.'))
.pipe(gulp.dest(envOptions.javascript.path))
.pipe(
browserSync.reload({
stream: true,
}),
);
}

這樣子原本發生的那幾個錯誤 Uncaught ReferenceError: require is not definedUncaught SyntaxError: redeclaration of const Urladmin-member.js:46:4note: Previously declared at line 2, column 6Uncaught ReferenceError: regeneratorRuntime is not defined 就都會得到解決哩。

而這些問題主要是與 @babel/core@babel/preset-env 的版本不同導致的,因此我們必須要將版本更新到一致,當然也跟 Gulp 套件有相關哩。

參考文獻