const path = require('path')
const BundleAnalyzerPlugin =
require('webpack-bundle-analyzer').BundleAnalyzerPlugin
// const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin')
const isProduction = process.env.NODE_ENV === 'production'
const isAnalyzeMode = !!process.env.ANALYZE_MODE
function resolve(dir) {
return path.join(__dirname, dir)
}
// 使用CDN 加速优化
const externals = {
wangeditor: 'wangEditor'
}
const cdnResource = {
css: ['https://unpkg.com/@wangeditor/editor@latest/dist/css/style.css'],
js: ['https://cdn.jsdelivr.net/npm/wangeditor@latest/dist/wangEditor.min.js']
}
// https://cli.vuejs.org/zh/guide/webpack.html#%E7%AE%80%E5%8D%95%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F
module.exports = {
devServer: {
// 配置反向代理
proxy: {
// 当地址中有/api的时候会触发代理机制
// '/api': {
// // 要代理的服务器地址 这里不用写 api
// target: 'http://localhost:4000',
// changeOrigin: true // 是否跨域
// }
'/prod-api': {
// 要代理的服务器地址 这里不用写 api
}
},
chainWebpack(config) {
if (isProduction | isAnalyzeMode) {
config.plugin('html').tap((args) => {
args[0].cdn = cdnResource
return args
})
}
// 设置 svg-sprite-loader
config.module.rule('svg').exclude.add(resolve('src/icons')).end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
},
configureWebpack: (config) => {
// https://webpack.js.org/configuration/cache/ 开启缓存
config.cache = {
type: 'filesystem',
allowCollectingMemory: true
}
// 打包时npm包转CDN
if (isProduction | isAnalyzeMode) {
config.externals = externals
}
config.optimization.splitChunks = {
maxInitialRequests: Infinity,
minSize: 300 * 1024,
chunks: 'all',
cacheGroups: {
elmVendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
// get the name.
// node_modules/packageName/sub/path
// or node_modules/packageName
const packageName = module.context.match(
/[\\/]node_modules[\\/](.*?)([\\/]|$)/
)[1]
return `npm.${packageName.replace('@', '')}`
}
}
}
}
if (isAnalyzeMode) {
config.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'static'
})
)
}
}
}
配置 externals
const externals = {
wangeditor: 'wangEditor'
}
配置 cdn
注意查看cdn 是否可以使用, 如果要上线,应该配置自己项目的cdn
const cdnResource = { css: ['https://unpkg.com/@wangeditor/editor@latest/dist/css/style.css'], js: ['https://cdn.jsdelivr.net/npm/wangeditor@latest/dist/wangEditor.min.js'] }
项目配置
chainWebpack(config) {
if (isProduction | isAnalyzeMode) {
config.plugin('html').tap((args) => {
args[0].cdn = cdnResource
return args
})
}
},
configureWebpack: (config) => {
// 打包时npm包转CDN
if (isProduction | isAnalyzeMode) {
config.externals = externals
}
},
页面配置
index.html
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title><%= htmlWebpackPlugin.options.title %></title>
<!-- 使用CDN的CSS文件 -->
<% for (var i in
htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
<link
href="<%= htmlWebpackPlugin.options.cdn.css[i] %>"
rel="preload"
as="style"
/>
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet" />
<% } %>
<!-- 使用CDN加速的JS文件,配置在vue.config.js下 -->
<% for (var i in
htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
</head>
<body>
<noscript>
<strong
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to
continue.</strong
>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
项目引入使用
<template>
<div class="editor-container">
<div id="editor-box"></div>
<div class="bottom">
<el-button type="primary" @click="onSubmitClick">{{
$t('msg.article.commit')
}}</el-button>
</div>
</div>
</template>
<script setup>
**import E from 'wangeditor'**
import { onMounted, defineProps, defineEmits, watch } from 'vue'
import i18next from 'i18next'
import { useStore } from 'vuex'
import { commitArticle, editArticle } from './commit'
console.log(E)
const props = defineProps({
title: {
required: true,
type: String
},
detail: {
type: Object
}
})
const emits = defineEmits(['onSuccess'])
const store = useStore()
// Editor实例
let editor
// 处理离开页面切换语言导致 dom 无法被获取
let el
onMounted(() => {
el = document.querySelector('#editor-box')
initEditor()
})
const initEditor = () => {
editor = new E(el)
editor.config.zIndex = 1
// 菜单栏提示
editor.config.showMenuTooltips = true
editor.config.menuTooltipPosition = 'down'
// 国际化相关处理
editor.config.lang = store.getters.language === 'zh' ? 'zh-CN' : 'en'
editor.i18next = i18next
editor.create()
}
// 编辑相关
watch(
() => props.detail,
(val) => {
if (val && val.content) {
editor.txt.html(val.content)
}
},
{
immediate: true
}
)
const onSubmitClick = async () => {
if (props.detail && props.detail._id) {
// 编辑文章
await editArticle({
id: props.detail._id,
title: props.title,
content: editor.txt.html()
})
} else {
// 创建文章
await commitArticle({
title: props.title,
content: editor.txt.html()
})
}
editor.txt.html('')
emits('onSuccess')
}
</script>
<style lang="scss" scoped>
.editor-container {
.bottom {
margin-top: 20px;
text-align: right;
}
}
</style>