可能很多同學(xué)還不知道 Farm , 先給大家介紹一下, Farm 是一個基于 Rust 的 Web 構(gòu)建工具, 類似 webpack 和 vite,但更快。 Farm 用 resolve, load, transform 把所有的 asset (js/jsx/ts/tsx、css/sass/less、html、靜態(tài)資源、json 等),并將它們打包成一系列可部署文件。 Farm 作為一個速度極快的構(gòu)建工具,可幫助您更快的構(gòu)建出 web / nodejs 應(yīng)用程序。
接下來就進入正題, 那么如何從已有的 vite 項目遷移到 Farm 呢 ?
從 vite 遷移到 farm 其實非常簡單, 因為 farm 內(nèi)置了對 vite 插件的兼容, 所以您只需要做的是將 vite.config.ts 轉(zhuǎn)換成 farm.config.js。
但是需要注意的是
我們先從基礎(chǔ)項目來體會一下從 vite 遷移到 Farm 有多簡單
首先還是我們熟悉的創(chuàng)建 vite 項目
pnpm create vite
我們選一個 Vue 項目模版, 創(chuàng)建好項目之后, 我們的 vite.config.ts 應(yīng)該是這樣的
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
})
那么把大象放進冰箱一共需要三步
pnpm install @farmfe/core @farmfe/cli -D
import { defineConfig } from '@farmfe/core'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
vitePlugins: [vue()],
})
然后我們在控制臺執(zhí)行 npx farm start 控制臺就可以看到以下命令
執(zhí)行構(gòu)建命令 npx farm build
這樣就大功告成啦, 是不是非常簡單。
接下來我們來遷移一個比較復(fù)雜的項目, vue-pure-admin 是一個全面ESM+Vue3+Vite+Element-Plus+TypeScript 編寫的一款后臺管理系統(tǒng), 并且模塊數(shù)量算是比較大, 那么我們使用 Farm 來遷移這個項目, 來進一步體現(xiàn)出 Farm 的優(yōu)勢. 以及遷移的成本到底有多低
首先我們先克隆一下 pure-admin 的倉庫代碼, 然后查看一下項目的 vite 配置文件, 并提示出遷移所需要修改的地方
import { getPluginsList } from "./build/plugins";
import { include, exclude } from "./build/optimize";
import { type UserConfigExport, type ConfigEnv, loadEnv } from "vite";
import {
root,
alias,
warpperEnv,
pathResolve,
__APP_INFO__
} from "./build/utils";
export default ({ mode }: ConfigEnv): UserConfigExport=> {
const { VITE_CDN, VITE_PORT, VITE_COMPRESSION, VITE_PUBLIC_PATH }=warpperEnv(loadEnv(mode, root));
return {
base: VITE_PUBLIC_PATH,
root,
resolve: {
alias
},
// 服務(wù)端渲染
server: {
// 端口號
port: VITE_PORT,
host: "0.0.0.0",
// 預(yù)熱文件以提前轉(zhuǎn)換和緩存結(jié)果,降低啟動期間的初始頁面加載時長并防止轉(zhuǎn)換瀑布
warmup: {
clientFiles: ["./index.html", "./src/{views,components}/*"]
}
},
plugins: getPluginsList(VITE_CDN, VITE_COMPRESSION),
// https://cn.vitejs.dev/config/dep-optimization-options.html#dep-optimization-options
optimizeDeps: {
include,
exclude
},
build: {
// https://cn.vitejs.dev/guide/build.html#browser-compatibility
target: "es2015",
sourcemap: false,
// 消除打包大小超過500kb警告
chunkSizeWarningLimit: 4000,
rollupOptions: {
input: {
index: pathResolve("./index.html", import.meta.url)
},
// 靜態(tài)資源分類打包
output: {
chunkFileNames: "static/js/[name]-[hash].js",
entryFileNames: "static/js/[name]-[hash].js",
assetFileNames: "static/[ext]/[name]-[hash].[ext]"
}
}
},
define: {
__INTLIFY_PROD_DEVTOOLS__: false,
__APP_INFO__: JSON.stringify(__APP_INFO__)
}
};
};
farm 配置基本平替 vite 配置, 我們再來看一下遷移到 farm 所需要修改的配置文件,由于對 css 的處理 farm 和 vite 的處理方向上的差異,所以我們只需要把一些 css 的插件配置替換成 farm 的插件, 其他的 vite 插件完全可以復(fù)用
import { getPluginsList } from "./build/plugins";
import { type UserConfigExport, type ConfigEnv, loadEnv } from "@farmfe/core";
import { root, alias, warpperEnv, __APP_INFO__ } from "./build/utils";
import postcss from "@farmfe/js-plugin-postcss";
import sass from "@farmfe/js-plugin-sass";
export default ({ mode }: ConfigEnv): UserConfigExport=> {
const { VITE_CDN, VITE_PORT, VITE_COMPRESSION, VITE_PUBLIC_PATH }=warpperEnv(loadEnv(mode, root)[0]);
return {
compilation: {
output: {
publicPath: VITE_PUBLIC_PATH,
targetEnv: "browser-es2015",
filename: "static/[ext]/[name]-[hash].[ext]",
assetsFilename: "static/[ext]/[name]-[hash].[ext]"
},
resolve: {
alias
},
script: {
plugins: [
{
name: "@swc/plugin-remove-console",
options: {
exclude: ["error"]
},
filters: {
moduleTypes: ["js", "ts", "jsx", "tsx"]
}
}
]
},
externalNodeBuiltins: false,
define: {
__INTLIFY_PROD_DEVTOOLS__: false,
__APP_INFO__: process.env.FARM_FE
? __APP_INFO__
: JSON.stringify(__APP_INFO__)
}
},
root,
// 服務(wù)端渲染
server: {
// open: true,
port: VITE_PORT
},
plugins: [
sass({
legacy: true
}),
postcss(),
{
name: "remove-css-filter-plugin",
priority: 0,
transform: {
filters: {
resolvedPaths: ["element-plus/dist/index.css"]
},
async executor({ content }) {
return {
content: content.replace(/filter:\s*alpha\(opacity=0\);/g, "")
};
}
}
}
],
vitePlugins: getPluginsList(VITE_CDN, VITE_COMPRESSION)
};
};
我們可以看到 vite 插件完全復(fù)用, 需要修改的地方僅僅是一些編譯輸出的屬性, 整體最大的修改點只有這些,我在 vue-pure-admin 項目提了一個 pr, 還有一些設(shè)計差異的小細節(jié)大家可以在這里 查看 盡管從 Vite 遷移到 Farm 需要進行一些調(diào)整和適配,但是這個過程并不復(fù)雜,而且可以通過優(yōu)化提升項目的性能和開發(fā)效率。因為確實遷移很簡單, 所以本篇文章只是簡單的介紹一下 Farm 目前的可用度,隨著 Farm 的不斷發(fā)展和完善,相信它會成為更多項目的首選構(gòu)建工具。
注:因為 vite 對于源代碼是請求時編譯,所以此處加上了 “項目可訪問時間”(即 “熱啟動時間” + “頁面加載時間”),作為另一個指標(biāo)來綜合對比性能。所以 Farm 在熱啟動比 vite 快 5 倍左右
farm 已經(jīng)具有了 所有開發(fā)調(diào)試 發(fā)布 也有很大的提升空間
Farm 開源已經(jīng)一年多了, 也已經(jīng)正式的發(fā)布了 1.0 版本, 已經(jīng)達到了生產(chǎn)可用的狀態(tài), 不僅僅是從 vite 中遷移, 在 webpack 中遷移, 團隊中也做了非常多的嘗試, 遷移成本都很低, Farm 下一步計劃基于 Farm 打造出下一代 SSR 框架, 也希望可以有更多的同學(xué)參與進來, 共同學(xué)習(xí)進步。
未來,我們將繼續(xù)撰寫更多的文章,深入介紹 Farm 的各項功能以及特性和原理解析,幫助大家更好地理解和使用下一代的構(gòu)建工具,可以對前端工程化以及代碼解析與編譯的原理理解之后, 可以更加深入地了解現(xiàn)代前端開發(fā)的核心概念和技術(shù),并掌握構(gòu)建高效、穩(wěn)定的前端項目的關(guān)鍵技能。讓我們共同期待未來的探索和發(fā)現(xiàn),共同探討前端技術(shù)的前沿話題,為構(gòu)建更加美好的 Web 世界貢獻一份力量。
鏈接:https://juejin.cn/post/7352837711339814963
迎搜索公眾號:白帽子左一
每天分享更多黑客技能,工具及體系化視頻教程(免費領(lǐng))
來源:HACK學(xué)習(xí)呀
一直找不到目標(biāo)站點,昨天下午收到的一條微信之后突然有了目標(biāo)
還是老規(guī)則 下載了APP 這里提示下注意事項
因為這種APP是自動采用微信賬號登錄 且蘋果手機登錄前需要申請數(shù)據(jù)網(wǎng)絡(luò)權(quán)限
所以在進行抓包前 ,需要先點開APP給予數(shù)據(jù)網(wǎng)絡(luò)權(quán)限并提前登錄微信賬號(設(shè)置代理之后無法登錄微信
進入APP后、 首先對APP內(nèi)部通過http請求獲取或得到數(shù)據(jù)的接口進行了測試, 也測試得到APP走http請求的IP為 ,阿里云服務(wù)器IP地址
注意事項 碰到阿里云服務(wù)器(不要進行端口掃描,不要進行網(wǎng)頁路徑探測)
因為這兩點都會讓阿里云封你的IP 首先對反饋接口進行了抓包 丟入了XSS
丟入xss 之后 考慮到這個APP并沒有什么可以入手的點
(本人比較菜,沒辦法在這上面找到突破口)
于是注意到這個APP有掛載的官網(wǎng),果斷從官網(wǎng)開始入手
首先找到了部分代理登錄的后臺,進入了登錄界面,因為有兩個登錄界面 一個是http 并且無驗證碼
一個是https 有驗證碼 首先從http無驗證碼口開始爆破密碼
https://jingyan.baidu.com/article/200957619c8739cb0721b4ff.html
Burp爆破網(wǎng)站后臺賬號密碼步驟
成功的登錄了后臺,發(fā)現(xiàn)后臺并沒有什么其他功能 只是能查看個人的代理及充值返利情況
在未找到直接能getshell的點, 首先對網(wǎng)站后臺進行了抓包, 查看后臺中部分搜索功能是否存在SQL注入,其次查看后臺是否存在邏輯漏
可以確定的點如下(網(wǎng)站后臺未存在有SQL注入,數(shù)據(jù)庫不進行報錯,對網(wǎng)站進行掃描并未封IP
IP地址為武漢,極有可能是源IP地址,接著繼續(xù)尋找網(wǎng)站的邏輯漏洞
當(dāng)咱們對myuser.php 進行訪問時 服務(wù)器緩存的cookie 信息為以上圖片內(nèi)
aliyungf_tc 為無效數(shù)據(jù) 可無視不計算
user_name 為賬號信息 user_id為服務(wù)器uid值 user_level為用戶等級
嘗試修改賬號信息為123456789 數(shù)據(jù)并未發(fā)生改變
嘗試修改uid值 數(shù)據(jù)發(fā)生改變
嘗試修改用戶等級 未發(fā)生改變
于是得到uid 值為判斷用戶的標(biāo)準(zhǔn)
接下來 就找我親愛的丁哥寫了套爬蟲 (用戶uid值為循環(huán)上升,爬取頁面內(nèi)容 得到網(wǎng)站總用戶量為1萬五千人)
之前咱們提到還有一個https的后臺
有驗證碼機制
有驗證碼機制進行爆破成功率可能并不是很高 嘗試進行找回密碼功能
修改uid值為空試試
點擊確認提交 直接來到了修改密碼的頁面
https://qy.xxxxxxx.com/user_goback_password.php?uid=
再進行uid補全為test用戶uid=11000 輸入更改的新密碼 更改成功
成功進入后臺 截止到目前為止
(拿到了網(wǎng)站全部用戶的個人信息,拿到了充值游戲幣的權(quán)限)
順便解釋下為什么能更改成功test用戶的密碼
當(dāng)user_goback_quan.php?uid=11000 修改為uid=空時
數(shù)據(jù)庫查詢不到用戶 那么對應(yīng)的答案也是查詢不到 為空的
更改密碼在數(shù)據(jù)庫判斷中 問題=答案(正確) ----- 更改成功
當(dāng)問題不存在 答案不存在的情況下 問題=答案 跳轉(zhuǎn)到更改密碼界面 — 更改uid值為test用戶uid=====成功更改test用戶密碼
// 在已經(jīng)創(chuàng)建好的項目中安裝插件
vue add element
// 安裝過程中的選項
? Successfully installed plugin: vue-cli-plugin-element
? How do you want to import Element? Fully import
? Do you wish to overwrite Element's SCSS variables? No
? Choose the locale you want to load zh-CN
npm run serve
// 運行結(jié)果
DONE Compiled successfully in 6537ms 22:40:55
App running at:
- Local: http://localhost:8080/
- Network: http://192.168.1.9:8080/
vue add router
? Installing @vue/cli-plugin-router...
+ @vue/cli-plugin-router@4.4.4
updated 1 package in 16.079s
42 packages are looking for funding
run `npm fund` for details
? Successfully installed plugin: @vue/cli-plugin-router
? Use history mode for router? (Requires proper server setup for index
fallback in production) No `N`
// 1.根據(jù)element Container 布局容器創(chuàng)建主界面
<template>
</template>
<script>
export default {
}
</script>
<style>
</style>
// 2.修改router下index.js
import Main from '../views/Main.vue'
{
path: '/',
name: 'main',
component: Main
}
// 3.簡化App.vue 只保留router-view
<div id="app">
<router-view/>
</div>
// 4.去除App.vue 中樣式,初始化樣式表 margin: 0;padding: 0;
// 5.修改Main.vue 中高度樣式表style="height: 100vh;"
//保留基本結(jié)構(gòu)
<template>
<el-container style="height: 100vh;">
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<el-menu :default-openeds="['1', '3']">
<el-submenu index="1">
<template slot="title"><i class="el-icon-message"></i>導(dǎo)航一</template>
<el-menu-item index="1-1">選項1</el-menu-item>
<el-menu-item index="1-2">選項2</el-menu-item>
<el-menu-item index="1-3">選項3</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header style="text-align: right; font-size: 12px">
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>查看</el-dropdown-item>
<el-dropdown-item>新增</el-dropdown-item>
<el-dropdown-item>刪除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<span>王小虎</span>
</el-header>
<el-main>
<el-table :data="tableData">
<el-table-column prop="date" label="日期" width="140">
</el-table-column>
<el-table-column prop="name" label="姓名" width="120">
</el-table-column>
<el-table-column prop="address" label="地址">
</el-table-column>
</el-table>
</el-main>
</el-container>
</el-container>
</template>
<style>
.el-header {
background-color: #B3C0D1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
<script>
export default {
data() {
const item={
date: '2020-08-08',
name: '墨客moke',
address: '青海省西寧市'
};
return {
tableData: Array(20).fill(item)
}
}
};
</script>
// 管理后臺客戶端分類列表創(chuàng)建
// Main.vue
// 1:新建分類、分類列表
// 2:添加 router 屬性
// 3:導(dǎo)航菜單添加路由
<el-menu router :default-openeds="['1']"> <!-- 導(dǎo)航菜單收縮 --> <!-- router屬性 -->
<el-submenu index="1">
<template slot="title"><i class="el-icon-message"></i>內(nèi)容管理</template>
<el-menu-item-group>
<template slot="title">分類</template>
<el-menu-item index="/categories/create">新建分類</el-menu-item>
<el-menu-item index="/categories/list">分類列表</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
為Main.vue
新建CategoriesEdit子組件
// 1.CategoriesEdit.vue
// 2.添加Main子路由
// 3.請求遠程數(shù)據(jù)接口
// 安裝插件
F:\client\node-vue-moba\admin>cnpm i axios
√ Installed 1 packages
√ Linked 3 latest versions
√ Run 0 scripts
√ All packages installed (4 packages installed from npm registry, used
593ms(network 587ms), speed 26.3kB/s, json 4(15.44kB), tarball 0B)
// 配置使用
// http.js
import axios from 'axios'
const http=axios.create({
baseURL : 'http://localhost:3000/admin/api'
})
export default http
// main.js 創(chuàng)建axios實例
import http from './http'
Vue.prototype.$http=http
查看相關(guān)內(nèi)容見 0x04CRUD接口開發(fā)
<template>
<div class="about">
<h1>{{id ? '編輯' : '新建'}}分類</h1>
<el-form label-width="120px" @submit.native.prevent="save">
<el-form-item label="名稱">
<el-input v-model="model.name"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" native-type="submit">保存</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
props:{
id:{}
},
data(){
return {
model:{}
}
},
methods:{
async save(){
// 列表新建和編輯數(shù)據(jù)更新
if (this.id) {
await this.$http.put(`categories/${this.id}`,this.model)
} else {
await this.$http.post('categories',this.model)
}
// 跳轉(zhuǎn)至分類列表
this.$router.push('/categories/list')
this.$message({
type: 'sucess',
message: '保存成功'
})
},
// 分類編輯1:獲取分類數(shù)據(jù)
// 分類編輯2:修改后更新數(shù)據(jù)
async fetch(){
const res=await this.$http.get(`categories/${this.id}`)
this.model=res.data
}
},
created(){
this.id && this.fetch()
}
}
</script>
<style>
</style>
<template>
<div class="about">
<h1>分類列表</h1>
<el-table :data="items">
<el-table-column prop="_id" label="ID" width="245"></el-table-column>
<el-table-column prop="name" label="分類名稱"></el-table-column>
<el-table-column fixed="right" label="操作" width="180">
<template slot-scope="scope">
<el-button type="text" size="small" @click="$router.push(`/categories/edit/${scope.row._id}`)">編輯</el-button>
<el-button type="text" size="small" @click="remove(scope.row)">刪除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data(){
return {
items:[]
}
},
methods:{
async fetch(){
const res=await this.$http.get('categories')
this.items=res.data
},
async remove(row){
this.$confirm(`是否確定刪除${row.name}?`, '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'warning'
}).then(async ()=> {
await this.$http.delete(`categories/${row._id}`),
this.$message({
type: 'success',
message: '刪除成功!'
});
this.fetch()
})
}
},
created(){
this.fetch()
}
}
</script>
<style>
</style>
感謝閱讀,歡迎交流。
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。