如果只有vue编译过后的前端文件,其他的文件夹都已经丢失。 这时候怎么把这个项目的源码还原呢?
1. vue反编译库 reverse-sourcemap
通过反编译 .map 文件, 得到编译前的 vue文件。
(1)安装
npm install --global reverse-sourcemap
(2)执行命令,会把对应的源文件,输出到src文件夹下。
reverse-sourcemap --output-dir src 0.xxxxxxxx.js.map
我们看到 dist/static/js 下有很多 xxxxx.js.map文件, 可以使用python写个脚本统一输出
import subprocess
from pathlib import Path
import os
# 反编译vue
# 进入 static目录
base_dir = "/data/dist"
output_dir = "src"
p = Path(base_dir)
files_list = p.rglob('*.map')
for file in files_list:
file_name = file.name
cmd = "reverse-sourcemap --output-dir {} {}".format(output_dir, str(file))
result = subprocess.check_output(cmd, shell=True)
print(result)
执行之后,我们就得到源码的文件, 在dist/src/static/js/webpack/src 里面。(根据原项目的编译路径)
同时 /static/js/ 下,编译过的js文件可以删除了,保留正常js文件。
反编译得到的 node_modules 目录在 dist/src/static/js/webpack 下。
2. 编排项目目录结构
找一个本地的vue项目(反编译得到的文件单独复制一份,后面会用到)
(1)把反编译得到的src、node_modules 文件夹替换原代码目录。
(2)把编译后的static文件夹, 替换原代码static目录。
(3)把编译后的index.html, 删掉引入的编译css、js代码部分, 同时查看是否有手动引入的静态js、css文件。在static文件夹中可以查找对应的路径,排查有没有误删。
简单的vue index.html示例
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1">
<title>test</title>
</head>
<body>
<div id=app></div>
</body>
</html>
3. node_modules包信息
npm shrinkwrap 是 npm 包管理器的一项功能,可以使用这个得到源码用到的库。
进入目录第2步备份的反编译node_modules目录下
执行命令 npm shrinkwrap,得到 npm-shrinkwrap.json 文件。
里面纪录了项目用到的npm包,但是没有版本号以及编译库。
我们查看node_modules目录下的库信息,确认vue、npm等重要库的版本号。
4. 启动项目
回到第2步,我们构建的项目中。
先修改原package.json,只保留编译用到的库。 比如我本地是 webpack。
贴一下我本地的package.json, 根据第3步情况修改
{
"name": "test",
"version": "0.0.1",
"description": "testweb",
"author": "",
"private": true,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"unit": "jest --config test/unit/jest.conf.js --coverage",
"e2e": "node test/e2e/runner.js",
"test": "npm run unit && npm run e2e",
"lint": "eslint --ext .js,.vue src test/unit test/e2e/specs",
"build": "node build/build.js"
},
"dependencies": {
"@babel/polyfill": "^7.12.1",
"@babel/runtime-corejs2": "^7.12.1",
"axios": "^0.21.0",
"babel-plugin-import": "^1.13.1",
"vconsole": "^3.15.0",
"vue": "^2.6.0",
"vue-clipboard2": "^0.3.3",
"vue-i18n": "^8.12.0",
"vue-json-viewer": "^2.2.22",
"vue-router": "^3.0.1",
"vuex": "^3.0.1"
},
"devDependencies": {
"@babel/cli": "^7.12.1",
"@babel/core": "^7.12.3",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.0.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.12.1",
"@babel/preset-env": "^7.12.1",
"@babel/runtime": "^7.12.1",
"@vue/babel-helper-vue-jsx-merge-props": "^1.2.1",
"@vue/babel-preset-jsx": "^1.2.4",
"acorn": "^7.4.1",
"autoprefixer": "^9.7.2",
"babel-loader": "^8.1.0",
"compression-webpack-plugin": "^6.0.5",
"copy-webpack-plugin": "^6.2.1",
"core-js": "^2.6.11",
"css-loader": "^5.0.0",
"eslint": "^7.12.1",
"eslint-friendly-formatter": "^4.0.1",
"eslint-loader": "^4.0.2",
"eslint-plugin-vue": "^7.1.0",
"file-loader": "^6.2.0",
"friendly-errors-webpack-plugin": "^1.7.0",
"html-webpack-plugin": "^4.5.0",
"mini-css-extract-plugin": "^1.2.1",
"node-notifier": "^8.0.0",
"node-sass": "^4.14.1",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"ora": "^5.1.0",
"postcss": "^8.1.4",
"postcss-import": "^13.0.0",
"postcss-loader": "^4.0.4",
"postcss-url": "^9.0.0",
"sass": "^1.27.0",
"sass-loader": "^10.0.4",
"shelljs": "^0.8.4",
"style-loader": "^2.0.0",
"stylus": "^0.54.8",
"stylus-loader": "^4.1.1",
"svg.draggable.js": "^3.0.0",
"svg.draw.js": "^2.0.4",
"svg.js": "^2.7.1",
"svg.resize.js": "^1.4.3",
"svg.select.js": "^3.0.1",
"terser-webpack-plugin": "^2.3.0",
"url-loader": "^4.1.1",
"vue-loader": "^15.9.5",
"vue-super-flow": "^1.3.6",
"vue-template-compiler": "^2.6.12",
"webpack": "^4.44.2",
"webpack-bundle-analyzer": "^4.8.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.8.0",
"webpack-merge": "^5.2.0"
},
"engines": {
"node": ">= 10.23.0",
"npm": ">= 6.14.8"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
执行npm run start, 根据报错提示,npm install –save 库,直到项目启动成功。
这一步没什么太好的办法,只能耐心查找依赖。
同时可以查看源码中引入的库,猜测大概的内容。
5. 生成package.json
如果项目启动成功,那么恭喜你,你已经把项目反编译成功了。
但是想得到package.json, 还需要做些工作。
在当前项目下执行命令 npm shrinkwrap,得到一个新的npm-shrinkwrap.json 文件。
然后根据第3步得到的npm-shrinkwrap.json 文件, 对照着新的得到库的版本和信息。
tips:
可以复制当前项目后, 生成一个新的目录, 删除node_modules。
在新目录中,npm run install 后, 再重新 npm run start。
根据报错提示,npm install –save 库,直到项目启动成功。(类似第4步操作)
ps: npm run start 的时候,要删除 npm-shrinkwrap.json