换个打包工具,Vite 迁移到 Farm ,踩坑!总结!现在前端有不少打包工具,[Farm](https://www.f
现在前端有不少打包工具,Farm
Rspack
Mako
等等 ,也许未来会出现更多。尽管Vite
已经够快了,不过对于新的东西,我是喜欢尝鲜的。Farm
对标的是Vite
,兼容大部分Vite
插件,手上正好有一个简单的大屏项目,花了一个下午迁移到Farm
上,老实说,迁移之路并不算平滑,记录一下迁移的历程。
初始工作
使用 Farm
只需要下载 @farmfe/cli
@farmfe/core
即可。
pnpm add -D @farmfe/cli @farmfe/core
然后在 vite.config.js
的同级目录下新建 farm.config.mjs
,这里需要注意,如果项目没有指定 "type": "module",
,那么必须新建为 farm.config.mjs
,farm.config.js
无法正常识别。然后将 vite.config.js
配置迁移到 farm.config.mjs
即可,不需要改动目录结构。
迁移配置项
vite.config.js
import { loadEnv, defineConfig } from "vite";
import { resolve } from "path";
import vue from "@vitejs/plugin-vue";
import { visualizer } from "rollup-plugin-visualizer";
import Components from "unplugin-vue-components/vite";
import { AntDesignVueResolver } from "unplugin-vue-components/resolvers";
import svgLoader from "vite-svg-loader";
// https://vitejs.dev/config/
export default ({ mode }) => {
return defineConfig({
base: "/databoard/",
publicDir: "public",
build: {
outDir: "dist",
assetsDir: "static",
rollupOptions: {
input: {
main: resolve(__dirname, "index.html"),
},
},
},
resolve: {
alias: {
"@": "/src",
},
},
css: {
preprocessorOptions: {
less: {
modifyVars: {
// 自定义Antdv主题
"primary-color": loadEnv(mode, process.cwd())
.VITE_APP_PRIMARY_COLOR,
"link-color": loadEnv(mode, process.cwd()).VITE_APP_PRIMARY_COLOR,
},
javascriptEnabled: true,
},
scss: {},
},
},
plugins: [
vue(),
svgLoader(),
visualizer(),
Components({
resolvers: [AntDesignVueResolver({ importStyle: "less" })],
}),
],
server: {
host: "0.0.0.0",
port: 8889,
proxy: {
// ...
},
},
});
};
我们逐个迁移
import
语句以及export default
函数不需要变动,配置项base
build
resolve
需要迁移到compilation
中
farm.config.mjs
import vue from "@vitejs/plugin-vue";
import { visualizer } from "rollup-plugin-visualizer";
import Components from "unplugin-vue-components/vite";
import { AntDesignVueResolver } from "unplugin-vue-components/resolvers";
import svgLoader from "vite-svg-loader";
import { loadEnv } from "@farmfe/core";
import path from "path";
export default ({ mode }) => {
return {
compilation: {
output: {
// base -> publicPath
publicPath: "/databoard/",
targetEnv: "browser-es2015",
// build.assetsDir -> assets
assetsFilename: "assets/[resourceName].[hash].[ext]",
},
resolve: {
alias: {
"@": path.join(process.cwd(), "src"),
},
},
},
};
};
这里需要注意
resolve.alias
,vite.config
是支持"@": "/src"
相对路径,但是farm.config
不支持,需要使用path.join
拼接出绝对路径。
Farm
虽然兼容Vite
插件,但是和Farm
自己的插件分别配置在两个配置项中。Farm
为Vite
插件提供了vitePlugins
配置项。
import vue from "@vitejs/plugin-vue";
import { visualizer } from "rollup-plugin-visualizer";
import Components from "unplugin-vue-components/vite";
import { AntDesignVueResolver } from "unplugin-vue-components/resolvers";
import svgLoader from "vite-svg-loader";
import less from "@farmfe/js-plugin-less";
import path from "path";
export default ({ mode }) => {
return {
// Vite 插件
vitePlugins: [
vue(),
svgLoader(),
visualizer(),
Components({
resolvers: [AntDesignVueResolver({ importStyle: "less" })],
}),
],
// Farm 插件
plugins: [],
};
};
css
配置,Farm 支持less
sass
,但不像 Vite 自带,需要引入 Farm 提供的插件:@farmfe/plugin-sass
@farmfe/js-plugin-less
。
pnpm add -D @farmfe/plugin-sass @farmfe/js-plugin-less
import less from "@farmfe/js-plugin-less";
export default ({ mode }) => {
// loadEnv 返回和 Vite 不同
const VITE_APP_PRIMARY_COLOR = loadEnv(mode, process.cwd())[0]
.VITE_APP_PRIMARY_COLOR;
return {
// Farm 插件
plugins: [
// @farmfe/plugin-sass 可以不用 import 引入
"@farmfe/plugin-sass",
// 将 css.preprocessorOptions 中的 less 配置项迁移到 这里
less({
lessOptions: {
modifyVars: {
// 自定义Antdv主题
"primary-color": VITE_APP_PRIMARY_COLOR,
"link-color": VITE_APP_PRIMARY_COLOR,
},
javascriptEnabled: true,
},
}),
],
};
};
在此处要注意,Farm
的 loadEnv
和 Vite
返回不一样,Vite
返回一个对象, 而 Farm
返回一个数组,需要使用 [0]
取出。
server
配置不用改动,但要注意,host
不要指定0.0.0.0
,否则会丢失hmr
功能。
export default ({ mode }) => {
return {
//...
server: {
// host: "0.0.0.0",
port: 8889,
proxy: {
//...
},
},
};
};
配置迁移完成,在 package.json
中添加命令,然后执行 pnpm dev:farm
即可启动项目。
{
"scripts": {
"dev:farm": "farm",
"build:farm": "farm build"
}
}
启动项目
不用想一次性启动成功,不出意外肯定要出意外。执行完命令后,显示报错
没有找到 ../images/shadow1.png
图片,这个代码是一个 css
类中的 background
属性引入的图片找不到。
.circle {
background: url(../images/shadow1.png) no-repeat scroll 100% 100%;
}
排查了下,这块属于粗心留下的无用代码,circle
类已经不再使用,图片也已经被删除。这在 Vite
中不会有影响,但是 Farm
可以排查出无法引入的资源,删除掉无用类后,项目成功启动。
但是打开页面后又出现了报错
这是因为在 store
中使用了 import.meta.glob
快捷绑定模块,Farm
是支持 Vite
的 import.meta.glob 功能的。
const files = import.meta.glob(`./users/*.js`);
Object.keys(files).forEach((key) => {
let name = key.replace(/(\.\/users\/|\.js)/g, "");
users[name] = files[key].default;
});
大屏项目下没有 user
目录,这块代码也属于无用代码。在 Vite
中可以正常运行,找不到会返回空对象。但是 Farm
找不到模块会报错。删除无用代码后,报错消失,但页面还是白屏,控制台有个警告:
找到 router
文件
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes,
});
问题就处在 import.meta.env.BASE_URL
,BASE_URL
是 Vite
特殊的环境变量,但是 Farm
中并没有,在 env
文件定义一个 VITE_API_BASE_URL
后,问题成功解决。
const router = createRouter({
history: createWebHistory(import.meta.env.VITE_API_BASE_URL),
routes,
});
至此,迁移完成,页面正常打开运行,hmr
功能正常,build
功能正常。
体验
这个项目确实小,不管是冷启动还是热启动,Farm
对比 Vite
都没有太让人惊喜的地方,也许放到大项目一次性请求几十个模块的时候才会有更明显的差距。
但在打包对比上,比 Vite
快了 10s
左右,不知道在大型项目上,差距会不会更明显,此外, Farm
的 build
是默认开启 sourcemap
的,如果不需要,可以在 compilation.sourcemap
中关闭。
总结
虽然迁移踩了一些坑,但好在都能解决,项目可以正常启动。建议可以在一些小项目中使用,dev
启动速度上差距不大,但如果项目配有 CI
CD
,build
还是有很可观的提升。
转载自:https://juejin.cn/post/7386568475488256052