您现在的位置是:首页 >技术教程 >vite+ts+elementplus运行正常打包报错网站首页技术教程
vite+ts+elementplus运行正常打包报错
vue3+vite+ts+elementPlus中运行正常打包出错
能正常运行,但是打包出错
下面是问题描述,解决办法看目录解决办法那一项
组件代码在最后面
vue3+vite+ts+elementPlus的项目中,我遇到了npm run dev可以正常运行,然后运行npm run build的时候就报错的情况,编译不过去,在这里记录一下,而且在vscode中与element plus相关的是爆红的,但是可以正常运行,只是打包不能正常打包而已。就会报错
如在vscode中报这个红,
无法找到模块“element-plus/dist/locale/zh-cn.mjs”的声明文件
还有就是引用element plus的一些组件的相关按需引入的时候爆红
模块 ““element-plus”” 没有导出的成员 “ElMessage”。你是想改用 “import ElMessage from “element-plus”” 吗?
模块 ““element-plus”” 没有导出的成员 “FormInstance”。你是想改用 “import FormInstance from “element-plus”” 吗?
虽然有这些爆红,但是npm run dev可以正常运行,运行结果如下
但是npm run build的时候打包就会报错,报错结果如下,就无法打包成功了,就是因为上面的那些爆红,所以导致打包失败。
TS7016: Could not find a declaration file for module ‘element-plus/dist/locale/zh-cn.mjs’. ‘D:/javastudykeshanchu/vite+ts+elementPlus/node_modules/element-plus/dist/locale/zh-cn.mjs’ implicitly has an ‘any’ type.
If the ‘element-plus’ package actually exposes this module, try adding a new declaration (.d.ts) file containingdeclare module 'element-plus/dist/locale/zh-cn.mjs';
5 import zhCn from ‘element-plus/dist/locale/zh-cn.mjs’
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~src/views/Home.vue:84:10 - error TS2614: Module ‘“element-plus”’ has no exported member ‘ElMessage’. Did you mean to use ‘import ElMessage from “element-plus”’ instead?
84 import { ElMessage, ElTable } from ‘element-plus’
具体如下截图
解决办法
element plus修改语言报错的解决办法
当出现:无法找到模块“element-plus/dist/locale/zh-cn.mjs”的声明文件
Could not find a declaration file for module ‘element-plus/dist/locale/zh-cn.mjs’.
在 .d.ts
文件中(如:vite在 vite-env.d.ts
文件)添加代码:
// 就加这一行就可以了
declare module "element-plus/dist/locale/zh-cn.mjs";
解决打包时出现导入element plus相关的爆红,导致无法打包的问题
如若出现类似于:Module ‘“element-plus”’ has no exported member ‘ElMessage’. Did you mean to use ‘import ElMessage from “element-plus”’ instead?
模块 ““element-plus”” 没有导出的成员 “ElMessage”。你是想改用 “import ElMessage from “element-plus”” 吗?
模块 ““element-plus”” 没有导出的成员 “FormInstance”。你是想改用 “import FormInstance from “element-plus”” 吗?
这样的问题,我们仅仅需要修改tsconfig.json文件下的,“moduleResolution”: “bundler”,改成"moduleResolution": “node即可”,
之所以出现上面这种(爆红)情况,是因为最新的vite构建的项目使用了typescript5.x的版本,而在这个版本中"moduleResolution": "bundler"是bundler而不是node
如我这里的typescript的版本是
这样的问题,我们仅仅需要修改tsconfig.json文件下的,“moduleResolution”: “bundler”,改成"moduleResolution": “node即可”,
改了之后,整个vue文件就不爆红了,
执行npm run dev运行看一下结果,也可以正常运行
然后执行npm run build,打包,打包的时候报什么样的错就根据错误进行改成就行了,如下面这里,element plus的import按需导入和语言切换已经解决了
之后执行 npm run build打包,就可以成功打包了
组件代码:
<template>
<div>
<h1>这个是Home组件</h1>
<el-button type="primary" @click="open2">success</el-button>
<el-row>
<el-table ref="multipleTableRef" :data="tableData" style="width: 100%" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="Date" width="120">
<template #default="scope">{{ scope.row.date }}</template>
</el-table-column>
<el-table-column property="name" label="Name" width="120" />
<el-table-column property="address" label="Address" show-overflow-tooltip />
</el-table>
<div style="margin-top: 20px">
<el-button @click="toggleSelection([tableData[1], tableData[2]])">Toggle selection status of second and third
rows</el-button>
<el-button @click="toggleSelection()">Clear selection</el-button>
</div>
</el-row>
<el-row>
<el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px" class="demo-ruleForm"
:size="formSize" status-icon>
<el-form-item label="Activity name" prop="name">
<el-input v-model="ruleForm.name" />
</el-form-item>
<el-form-item label="Activity zone" prop="region">
<el-select v-model="ruleForm.region" placeholder="Activity zone">
<el-option label="Zone one" value="shanghai" />
<el-option label="Zone two" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="Activity count" prop="count">
<el-select-v2 v-model="ruleForm.count" placeholder="Activity count" :options="options" />
</el-form-item>
<el-form-item label="Activity time" required>
<el-col :span="11">
<el-form-item prop="date1">
<el-date-picker v-model="ruleForm.date1" type="date" label="Pick a date" placeholder="Pick a date"
style="width: 100%" />
</el-form-item>
</el-col>
<el-col class="text-center" :span="2">
<span class="text-gray-500">-</span>
</el-col>
<el-col :span="11">
<el-form-item prop="date2">
<el-time-picker v-model="ruleForm.date2" label="Pick a time" placeholder="Pick a time"
style="width: 100%" />
</el-form-item>
</el-col>
</el-form-item>
<el-form-item label="Instant delivery" prop="delivery">
<el-switch v-model="ruleForm.delivery" />
</el-form-item>
<el-form-item label="Activity type" prop="type">
<el-checkbox-group v-model="ruleForm.type">
<el-checkbox label="Online activities" name="type" />
<el-checkbox label="Promotion activities" name="type" />
<el-checkbox label="Offline activities" name="type" />
<el-checkbox label="Simple brand exposure" name="type" />
</el-checkbox-group>
</el-form-item>
<el-form-item label="Resources" prop="resource">
<el-radio-group v-model="ruleForm.resource">
<el-radio label="Sponsorship" />
<el-radio label="Venue" />
</el-radio-group>
</el-form-item>
<el-form-item label="Activity form" prop="desc">
<el-input v-model="ruleForm.desc" type="textarea" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm(ruleFormRef)">
Create
</el-button>
<el-button @click="resetForm(ruleFormRef)">Reset</el-button>
</el-form-item>
</el-form>
</el-row>
</div>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { ElMessage, ElTable } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
const open2 = () => {
ElMessage({
message: 'Congrats, this is a success message.',
type: 'success',
})
}
interface User {
date: string
name: string
address: string
}
const multipleTableRef = ref<InstanceType<typeof ElTable>>()
const multipleSelection = ref<User[]>([])
const toggleSelection = (rows?: User[]) => {
if (rows) {
rows.forEach((row) => {
// 这个是表格的复选框勾选项
multipleTableRef.value!.toggleRowSelection(row, true)
})
} else {
multipleTableRef.value!.clearSelection()
}
}
const handleSelectionChange = (val: User[]) => {
multipleSelection.value = val
}
const tableData: User[] = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-08',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-06',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-07',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
]
// 表单
const formSize = ref('default')
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive({
name: 'Hello',
region: '',
count: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: '',
})
const rules = reactive<FormRules>({
name: [
{ required: true, message: 'Please input Activity name', trigger: 'blur' },
{ min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' },
],
region: [
{
required: true,
message: 'Please select Activity zone',
trigger: 'change',
},
],
count: [
{
required: true,
message: 'Please select Activity count',
trigger: 'change',
},
],
date1: [
{
type: 'date',
required: true,
message: 'Please pick a date',
trigger: 'change',
},
],
date2: [
{
type: 'date',
required: true,
message: 'Please pick a time',
trigger: 'change',
},
],
type: [
{
type: 'array',
required: true,
message: 'Please select at least one activity type',
trigger: 'change',
},
],
resource: [
{
required: true,
message: 'Please select activity resource',
trigger: 'change',
},
],
desc: [
{ required: true, message: 'Please input activity form', trigger: 'blur' },
],
})
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
console.log('submit!')
} else {
console.log('error submit!', fields)
}
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
}
const options = Array.from({ length: 10000 }).map((_, idx) => ({
value: `${idx + 1}`,
label: `${idx + 1}`,
}))
</script>
<style scoped></style>
vue3项目打包之后双击index.html是一片空白
这里我使用了路由的形式,打包之后双击 index.html网站显示一片空白,f12之后报如下所示的错误
我这里的路由配置是:
import { createRouter, createWebHashHistory } from "vue-router";
const routes = [
{
path: '/',
redirect: '/home'
},
{
path: '/helloworld',
component: () => import('../views/HelloWorld.vue')
},
{
path: '/home',
component: () => import('../views/Home.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
routes: routes
})
export default router
这个是直接在打包的dist文件夹下双击代开index.html,页面一片空白,所报的错误如下,这里有跨域问题,
assets/index-bf854284.js’ from origin ‘null’ has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome-untrusted, https, edge.
如果是使用vscode的发布服务打开的话,具体报错如下
报错信息如下
Found)
index.html:12 Refused to apply style from ‘http://127.0.0.1:5500/assets/index-5d2d5719.css’ because its MIME type (‘text/html’) is not a supported stylesheet MIME type, and strict MIME checking is enabled.
index.html:42 Live reload enabled.
:5500/vite.svg:1index.html:1 Refused to apply style from ‘http://127.0.0.1:5500/assets/index-5d2d5719.css’ because its MIME type (‘text/html’) is not a supported stylesheet MIME type, and strict MIME checking is enabled.
然后在vite.config.ts中进行如下配置
保存,npm run build重新打包,使用vscode服务的形式打开重新打包的index.html文件
能正常访问,就可以解决页面空白问题了,也可以根据路由切换不用的页面
但是下面这种双击打开方式还是有跨域问题,页面还是空白。这个暂时不知道怎么回事,还在找解决办法中,这种或许可以通过nginx解决,后面再说
通过nginx配置进行打包的部署
首先,将上面打包得到的dist文件复制到nginx对应的目录下,然后配置nginx,具体配置如下(可以使用vscode打开nginx.config),监听的端口号为8083。
启动nginx,如果之前已经启动了,记得先停用之后再配置,之后再双击启动nginx
启动nginx之后,访问http://localhost:8083,就可以了,之后就会得到如下的界面,改变路由地址也可以正常访问