初始化項目文件
$ vue init mpvue/mpvue-quickstart fuck
$ cd fuck
$ npm install
這個時候就初始化好了,接下來
$ npm run dev:tt
生成字節跳動的小程序項目,就是 'dist/tt/' 目錄。
運行字節跳動開發者工具
打開字節跳動開發者工具,導入上一步生成的目錄,等待編譯,結果會發現:

報錯了,我把報錯文本拷貝出來:
Error: Unable to determine project type, microApp needs app.json,microGame needs game.json.
at BuildDist (/Applications/bytedanceide.app/Contents/Resources/app.asar.unpacked/node_modules/byted-tma-pack/dest/index.js:1:64782)
at /Applications/bytedanceide.app/Contents/Resources/app.asar.unpacked/node_modules/byted-tma-pack/dest/index.js:1:67510
at i (/Applications/bytedanceide.app/Contents/Resources/app.asar.unpacked/simulator-sdk/dist/preload/compilePreload.3b7fe257013e358e1fa6.js:29:15959)
詳細報錯信息請查看控制台
報錯意思是無法判斷項目是小程序還是小游戲,因為找不到 app.json 或 game.json 文件。
然后 app.json 明明就安靜的躺在那里啊,什么情況!
根據報錯信息找到報錯文件 /Applications/bytedanceide.app/Contents/Resources/app.asar.unpacked/node_modules/byted-tma-pack/dest/index.js
美化一下 js 代碼,找到報錯的地方:
async function BuildDist(e) {
let {
compile: t,
splitJS: r,
isWatch: n,
buildType: a,
compile_mode: o
} = e || {};
const i = Date.now(),
s = commonjsGlobal.argvProject.tea;
console.time("-> microapp/index");
const l = microapp;
console.timeEnd("-> microapp/index"), console.time("require microgame/index");
const c = microgame;
console.timeEnd("require microgame/index"), debug_1.log(`[start build ${colors.red(a)}]`);
try {
switch (a) {
case "app":
console.time("/// ALL BUILD DONE ///"), await l(r, n, o), console.timeEnd("/// ALL BUILD DONE ///");
break;
case "game":
await c(r);
break;
default:
throw new Error("Unable to determine project type, microApp needs app.json,microGame needs game.json.")
}
} catch (e) {
if (commonjsGlobal.argvProject.isIDE) {
if (!commonjsGlobal.argvProject.isIDEForThird) return commonjsGlobal.argvProject.finishBuildCb(e)
} else debug_1.error(e), process.exit(1)
}
const p = Date.now() - i;
console.log("BuildDist:", `${p}ms`), s.collectEvent(teaConfig_1.totalCompileTime, {
compile_time: p,
compile_mode: o
}), await afterBuild(a, t)
}
就是在這個函數 throw Error 的,這個 a 有問題,也就是 buildType 有毛病,繼續回溯,找到:
var r2d2 = async function(e, t) {
let {
isProduction: r,
sourcePath: n,
isIde: a,
tarPath: o = "",
compileChannel: i = "",
assetsOrder: s,
minify: l
} = e;
__cwd$1 = n, targetFilePath = o;
const c = getProjectType(),
p = "-d" === a || "-l" === a;
let u = tea({
__cwd: __cwd$1,
buildType: c,
isIDE: p
}),
h = {
isProduction: r,
isIDE: p,
isIDEForThird: "-l" === a,
isRemoteDebugForTT: "-r" === a,
targetPath: targetFilePath,
__cwd: __cwd$1,
finishBuildCb: t,
compileChannel: i,
assetsOrder: s,
minify: l,
tea: u
},
g = {
compile: !1,
splitJS: !1,
isWatch: !1,
buildType: c,
compile_mode: "all"
};
commonjsGlobal.argvProject = h, "-c" === r ? (g.compile = !0, g.splitJS = !0, commonjsGlobal.argvProject.isIDE && !commonjsGlobal.argvProject.isIDEForThird ? (g.isWatch = !0, WatchCompile(g)) : await BuildDist(g)) : ("-b" === r && (g.splitJS = !0), Clear([path$2.resolve(__dirname, "../public/__dist__*"), path$2.resolve(__dirname, "../public/app.ttpkg.js")]).then(() => {
ServePbulic(), g.isWatch = !0, WatchCompile(g)
}))
};
也就是 getProjectType 會返回 buildType,它的返回值有貓膩,再看這個函數:
function getProjectType() {
const e = readjson.sync(`${__cwd$1}/project.config.json`).miniprogramRoot || "";
return fs.existsSync(path$2.join(__cwd$1, e, "app.json")) ? "app" : fs.existsSync(path$2.join(__cwd$1, e, "game.json")) ? "game" : "unknow"
}
咦!!它讀了 project.config.json,然后根據文件里 json 中的 miniprogramRoot 來尋找 app.json 和 game.json
馬上看一下 project.config.json 文件,果然里面配置了 miniprogramRoot,而且還是 "miniprogramRoot": "dist/wx/"
這就顯然不對了,最起碼也該把 wx 換乘 tt 吧。
然而就算換了 tt 也不行,miniprogramRoot 是個相對路徑,相對於當前項目路徑,也就是 fuck/dist/tt/ 目錄,其實也就是當前目錄,所以這個值應該是
{
"miniprogramRoot": "./"
}
然鵝,然鵝,直接修改這個文件並不合適,應該找到 fuck 目錄下單的 project.config.json,修改它里面的 miniprogramRoot,這樣就每次自動生成正確的文件了。
改好之后,mpvue 自動重新編譯生成新的項目文件,在字節跳動開發者工具中點擊編譯,pia~,頁面出來了,beautiful~
在手機上預覽一下,OK~
最后
我最終是直接吧 "miniprogramRoot": "dist/wx/" 這一句刪掉的。效果一樣
