随着公司各个项目体积的增大,开发环境项目的构建常常能达到一分钟甚至更长,使用vite能快速帮助我们提升项目的构建速度,于是最近开始对公司的项目进行改造,同时为了节省时间成本,生产的环境的构建打算沿用原本webpack的那套配置,仅仅将开发环境由webpack转为vite。
一、安装vite相关依赖
"vite": "^2.7.13",
"vite-plugin-html": "^2.1.2",
"vite-plugin-vue2": "^1.9.3",
二、修改的位置
将移至根目录下,而非public中,并且在html中引入入口js文件
<script type="module" src="/src/"></script>
三、修改ts的配置文件
//
{
"compilerOptions": {
...
"types": [
...
"vite/client"
],
},
...
}
四、修改启动命令
使用npm run serve
启动项目
"scripts": {
"start": "npm run serve",
"serve": "vite --port 8764",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"lint": "vue-cli-service lint"
},
五、开发环境改为vite的报错修复
1. 别名@需要在重新配置
export default defineConfig({
...
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
...
})
2. ts装饰器在vite启动时报错vite error: Unexpected "@" @Component
原因:EcmaScript 还没有正式支持 JS 装饰器,导致没有明确地将它们的
解决方法:将 <script>
替换为 <script lang="ts">
3. require('script-loader!file-saver');
报错
原因:ESBuild不支持commonjs,,vite中所有所以的commonjs语法必须转化成ESM
解决方法:将 require('script-loader!xlsx/dist/');
替换为 new URL('script-loader!xlsx/dist/', ).href;
类似var CryptoJS = require('crypto-js');
这种也需要转成import CryptoJS from 'crypto-js';
4. less语法报错variable @primaryColor is undefined
原因:未在中注入less全局变量
解决方法:新增配置
export default defineConfig({
...
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
additionalData: `@import ${getLessVariables(
resolve('src/assets/less/'),
)}`,
},
},
},
...
})
5.
报错
改为
glob表达式的语法有不懂的可以在github上查找相关文档
// const _modules = ('./modules', true, /\.ts$/);
const _modules = import.meta.globEager('./modules/*.ts');
- : 通过动态导入默认懒加载,通过遍历加 then 方法可拿到对应的模块文件详情信息
- : 直接引入所有的模块, 即静态 import
6. 在中支持ejs语法
首先在中配置变量ENV
import { minifyHtml, injectHtml } from 'vite-plugin-html';
export default defineConfig({
...
plugins: [
createVuePlugin(),
minifyHtml(),
injectHtml({
data: {
ENV: 'develop',
},
}),
],
...
})
在html中文件使用变量做判断
<% if (ENV === 'develop') { %>
<script type="module" src="/src/"></script>
<% } %>
六、生产环境构建报错修复
在使用vite命令本地构建项目无误之后,尝试在本地使用npm run build
构建生产环境的文件的时候出现了一些问题
1、与vite支持的语法冲突
解决方法:webpack引入相应loader,babel引入相应的plugins兼容vite语法
安装这两个依赖
//
"@open-wc/webpack-import-meta-loader": "^0.4.7",
"babel-preset-vite": "^1.0.4",
分别在和中配置
//
module.exports = {
presets: ['babel-preset-vite', ['@vue/app', { useBuiltIns: 'entry' }]],
};
//
module.exports = {
...
chainWebpack: config => {
const jsRule = config.module.rule('js');
const tsRule = config.module.rule('ts');
jsRule.uses.clear();
tsRule.uses.clear();
/**
* @open-wc/webpack-import-meta-loader
* Webpack loader for supporting `` in webpack.
*
* 在babel配置文件中使用babel-preset-vite兼容语法
*/
jsRule
.use(require.resolve('@open-wc/webpack-import-meta-loader'))
.loader(require.resolve('@open-wc/webpack-import-meta-loader'))
.end()
.use('happypack/loader?id=babel')
.loader('happypack/loader?id=babel')
.end();
// 处理ts文件
tsRule
.use(require.resolve('@open-wc/webpack-import-meta-loader'))
.loader(require.resolve('@open-wc/webpack-import-meta-loader'))
.end()
.use('cache-loader')
.loader('cache-loader')
.options({
cacheDirectory: resolve('node_modules/.cache/ts-loader'),
})
.end()
.use('babel-loader')
.loader('babel-loader')
.end()
.use('ts-loader')
.loader('ts-loader')
.options({
transpileOnly: true, // 关闭类型检查,即只进行转译(类型检查交给webpack插件(fork-ts-checker-webpack-plugin)在另一个进程中进行,这就是所谓的多进程方案,如果设置transpileOnly为false, 则编译和类型检查全部由ts-loader来做, 这就是单进程方案.显然多进程方案速度更快)
appendTsSuffixTo: ['\\.vue$'],
happyPackMode: false,
})
.end();
// 使用webpack 插件进行typescript 的类型检查 fork-ts-checker-webpack-plugin
config.plugin('fork-ts-checker').use(ForkTsCheckerWebpackPlugin, [
{
vue: true,
tslint: false,
formatter: 'codeframe',
checkSyntacticErrors: false,
// 因为fork-ts-checker-webpack-plugin是在单独的进程跑的,所以它的错误或警告信息是异步回传给到webpack进程的, 这时编译报错信息只在终端显示,不会在预览的浏览器界面显示报错信息。
// 将async设置为false后,就要求webpack等待fork-ts-checker-webpack-plugin进程返回信息, 这样会在页面显示编译报错信息。不过这样做也可能会拖慢整个webpack的转译等待时间。
// async: false
},
]);
config.resolve
.set('symlinks', false)
.extensions.merge(['.js', '.json', '.vue', '.ts'])
.end();
},
...
}
但是在npm上看到babel-preset-vite的说明有这样一句话
The functionality within these transformations should not be relied upon in production.
也就是说不建议放在将babel-preset-vite配置在生产环境。。但是他没有说为什么不能用在生产环境,也没有给出生产环境的替代方案,所以暂时只能这样发到测试环境,目前还没有发现什么问题,如果有解决方案的小伙伴可以告知我,一起学习一下~