网站版面的美化原则odoo做网站

张小明 2026/1/1 3:01:14
网站版面的美化原则,odoo做网站,晋安福州网站建设,网站图片上传却不显示不出来一、前置认知#xff1a;工程化的核心价值与职场痛点随着前端项目规模扩大#xff0c;团队人数增加#xff0c;“手动开发”的弊端愈发凸显#xff1a;某中型互联网公司的电商项目#xff0c;3名前端开发者因未统一代码规范#xff0c;每周需花费15小时解决代码冲突…一、前置认知工程化的核心价值与职场痛点随着前端项目规模扩大团队人数增加“手动开发”的弊端愈发凸显某中型互联网公司的电商项目3名前端开发者因未统一代码规范每周需花费15小时解决代码冲突某创业团队因缺乏自动化构建流程每次上线需手动修改10余个文件路径上线故障率高达20%某大型企业的管理系统因未做模块化拆分单个页面JS文件体积超过2MB首屏加载时间长达8秒用户流失率提升40%。前端工程化的核心目标是通过“标准化、自动化、模块化、可监控”的手段解决“代码混乱、协作低效、上线繁琐、性能失控、维护困难”五大痛点实现“多人高效协作、项目稳定交付、质量可追溯、成本可控”的业务目标。对前端工程师而言工程化能力是从“单兵作战”到“团队核心”的关键标志——字节、阿里、美团等大厂的前端岗位均将工程化经验作为中高级人才的核心考核指标。职场关键认知工程化不是“炫技”而是“按需落地”。小型项目无需引入复杂的微前端架构中型项目重点解决构建和协作问题大型项目才需要完善的监控和灰度发布体系。脱离业务规模的工程化只会增加研发成本。二、Day55构建工具进阶——从“基础打包”到“按需优化”构建工具是工程化的“基石”负责代码的编译、打包、压缩、优化等核心流程。当前主流构建工具为Vite和Webpack前者基于ES Module实现极速冷启动后者基于模块化打包适用于复杂场景需根据项目规模精准选型。1. 主流构建工具对比与选型指南构建工具的核心差异在于“模块解析方式”“构建速度”和“生态完善度”直接决定了开发效率和项目性能工具类型核心优势核心劣势适用场景代表场景Vite新一代冷启动速度极快毫秒级、热更新高效、配置简洁、支持按需编译对旧浏览器兼容性差需配合vitejs/plugin-legacy、复杂场景插件生态不如Webpack成熟现代前端项目Vue3/React18项目、中小型应用、需要快速迭代的项目管理后台、移动端H5、小程序前置项目Webpack成熟稳定生态完善插件超过2000个、兼容性好、支持复杂场景如多页面、微前端、可定制性强冷启动速度慢大型项目需数十秒、配置复杂、热更新效率随项目规模下降复杂大型项目多页面应用、需兼容旧浏览器的项目、微前端主应用电商平台、门户网站、企业级复杂应用职场选型技巧新项目优先选择Vite利用其快速开发优势提升效率若项目需兼容IE11等旧浏览器或依赖Webpack专属插件如html-webpack-plugin高级用法则选用Webpack。可通过“Vite开发Webpack构建”组合兼顾效率与兼容性。2. 实战1Vite高级配置性能优化多环境适配Vite默认配置已能满足基础需求针对中大型项目需进行高级优化重点解决“兼容性”“打包体积”“构建速度”问题// vite.config.js 完整配置 import { defineConfig, loadEnv } from vite import vue from vitejs/plugin-vue import legacy from vitejs/plugin-legacy // 兼容旧浏览器 import viteCompression from vite-plugin-compression // 压缩产物 import path from path import { visualizer } from rollup-plugin-visualizer // 打包体积分析 import eslintPlugin from vite-plugin-eslint // 代码校验 // 路径别名函数 const resolve (dir) path.resolve(__dirname, dir) export default defineConfig(({ mode }) { // 加载环境变量区分开发/测试/生产 const env loadEnv(mode, process.cwd(), ) return { // 基础配置 base: env.VITE_BASE_URL, // 部署基础路径开发环境 /生产环境 /admin/ resolve: { alias: { : resolve(src), // 别名配置指向src目录 components: resolve(src/components), utils: resolve(src/utils) }, extensions: [.vue, .js, .ts, .json] // 省略后缀名 }, // 服务器配置开发环境 server: { host: 0.0.0.0, // 允许外部访问 port: 8080, // 端口号 open: true, // 自动打开浏览器 proxy: { // 接口代理解决跨域 /api: { target: env.VITE_API_BASE_URL, // 后端接口地址环境变量区分 changeOrigin: true, // 开启跨域 rewrite: (path) path.replace(/^\/api/, ) // 重写路径 } } }, // 构建配置生产环境 build: { outDir: dist, // 输出目录 assetsDir: static, // 静态资源目录 sourcemap: env.VITE_SOURCEMAP true, // 生产环境是否生成sourcemap调试用 // 打包优化 rollupOptions: { // 代码分割将第三方依赖单独打包 output: { chunkFileNames: static/js/[name]-[hash].js, entryFileNames: static/js/[name]-[hash].js, assetFileNames: static/[ext]/[name]-[hash].[ext], manualChunks: { // 把vue相关依赖打包成一个chunk vue: [vue, vue-router, pinia], // 把第三方工具库打包成一个chunk utils: [axios, lodash-es] } } }, // 压缩配置 minify: terser, // 使用terser压缩比esbuild压缩率更高 terserOptions: { compress: { drop_console: env.VITE_ENV production, // 生产环境删除console drop_debugger: env.VITE_ENV production // 生产环境删除debugger } } }, // 插件配置 plugins: [ vue(), // 兼容旧浏览器IE11 legacy({ targets: [defaults, ie 11], additionalLegacyPolyfills: [regenerator-runtime/runtime] }), // 生产环境开启gzip压缩 env.VITE_ENV production viteCompression({ algorithm: gzip, // 压缩算法 threshold: 10240, // 超过10kb的文件才压缩 deleteOriginFile: false // 不删除原文件 }), // 打包体积分析仅在需要时开启 env.VITE_ANALYZE true visualizer({ open: true, filename: dist/visualizer.html }), // 代码校验开发环境开启 env.VITE_ENV ! production eslintPlugin({ cache: true, // 开启缓存 include: [src/**/*.vue, src/**/*.js] // 校验范围 }) ], // CSS配置 css: { preprocessorOptions: { // 全局注入SCSS变量 scss: { additionalData: import /styles/variables.scss; } }, // 开启CSS分离生产环境 extract: env.VITE_ENV production, // CSS压缩 devSourcemap: false } } })环境变量配置.env.development/.env.production# .env.development开发环境 VITE_ENVdevelopment VITE_BASE_URL/ VITE_API_BASE_URLhttp://localhost:3000 VITE_SOURCEMAPfalse VITE_ANALYZEfalse # .env.production生产环境 VITE_ENVproduction VITE_BASE_URL/admin/ VITE_API_BASE_URLhttps://api.example.com VITE_SOURCEMAPfalse VITE_ANALYZEtrue3. 实战2Webpack性能优化大型项目适配Webpack针对大型项目的核心优化方向是“提升构建速度”和“减小打包体积”重点优化 loader 执行、模块解析和代码分割// webpack.config.js 核心优化配置 const path require(path) const HtmlWebpackPlugin require(html-webpack-plugin) const TerserPlugin require(terser-webpack-plugin) const MiniCssExtractPlugin require(mini-css-extract-plugin) const CssMinimizerPlugin require(css-minimizer-webpack-plugin) const { CleanWebpackPlugin } require(clean-webpack-plugin) const BundleAnalyzerPlugin require(webpack-bundle-analyzer).BundleAnalyzerPlugin const HappyPack require(happypack) // 多线程打包 const os require(os) const happyThreadPool HappyPack.ThreadPool({ size: os.cpus().length }) // 根据CPU核心数设置线程数 module.exports (env) { const isProduction env.production return { entry: { app: ./src/main.js, // 主入口 vendor: [vue, vue-router] // 第三方依赖单独入口 }, output: { path: path.resolve(__dirname, dist), filename: isProduction ? static/js/[name].[contenthash:8].js : static/js/[name].js, chunkFilename: isProduction ? static/js/[name].[contenthash:8].chunk.js : static/js/[name].chunk.js, publicPath: isProduction ? /admin/ : / }, // 缓存优化提升二次构建速度 cache: { type: filesystem, // 使用文件系统缓存 buildDependencies: { config: [__filename] // 配置文件变化时缓存失效 } }, // 模块解析优化 resolve: { extensions: [.js, .vue, .json], alias: { : path.resolve(__dirname, src), vue$: vue/dist/vue.esm.js }, // 减少模块查找范围 modules: [path.resolve(__dirname, node_modules)], // 只采用main字段作为入口文件描述 mainFields: [main] }, // 模块规则优化 module: { // 排除不需要处理的目录 noParse: /^(vue|vue-router|axios)$/, rules: [ { test: /\.js$/, // 使用HappyPack多线程处理JS编译 use: happypack/loader?idjs, include: path.resolve(__dirname, src), exclude: /node_modules/ }, { test: /\.vue$/, use: vue-loader, include: path.resolve(__dirname, src) }, { test: /\.css$/, // 生产环境分离CSS开发环境使用style-loader use: [ isProduction ? MiniCssExtractPlugin.loader : style-loader, css-loader, postcss-loader ] }, { test: /\.(png|jpe?g|gif|svg)$/, type: asset, parser: { dataUrlCondition: { maxSize: 8 * 1024 // 8kb以下的图片转base64 } }, generator: { filename: static/img/[name].[hash:8][ext] } } ] }, // 插件配置 plugins: [ // 清除输出目录 new CleanWebpackPlugin(), // 生成HTML文件 new HtmlWebpackPlugin({ template: ./public/index.html, filename: index.html, minify: isProduction ? { removeComments: true, // 删除注释 collapseWhitespace: true // 压缩空格 } : false }), // 生产环境分离CSS isProduction new MiniCssExtractPlugin({ filename: static/css/[name].[contenthash:8].css, chunkFilename: static/css/[name].[contenthash:8].chunk.css }), // 多线程处理JS new HappyPack({ id: js, threadPool: happyThreadPool, loaders: [babel-loader?cacheDirectorytrue] // 开启babel缓存 }), // 打包体积分析 isProduction new BundleAnalyzerPlugin({ openAnalyzer: false // 不自动打开分析页面 }) ].filter(Boolean), // 过滤掉false的插件 // 优化配置 optimization: { // 代码分割 splitChunks: { chunks: all, // 对所有chunk进行分割 minSize: 20000, // 最小体积20kb minRemainingSize: 0, minChunks: 1, // 最少被引用1次 maxAsyncRequests: 30, // 异步请求最大并发数30 maxInitialRequests: 30, // 初始请求最大并发数30 cacheGroups: { // 第三方依赖分割 vendor: { test: /[\\/]node_modules[\\/]/, name: vendors, priority: -10, // 优先级高于默认 reuseExistingChunk: true }, // 公共组件分割 common: { name: common, minChunks: 2, // 最少被引用2次 priority: -20, reuseExistingChunk: true } } }, // 运行时chunk分离 runtimeChunk: single, // 压缩优化 minimizer: [ // JS压缩 new TerserPlugin({ parallel: os.cpus().length 1, // 多线程压缩 terserOptions: { compress: { drop_console: isProduction, drop_debugger: isProduction } } }), // CSS压缩 isProduction new CssMinimizerPlugin() ].filter(Boolean) }, // 开发工具 devtool: isProduction ? source-map : cheap-module-eval-source-map, // 开发服务器 devServer: { host: 0.0.0.0, port: 8080, open: true, hot: true, // 热更新 proxy: { /api: { target: http://localhost:3000, changeOrigin: true, pathRewrite: { ^/api: } } } } } }三、Day56模块化与规范化——多人协作的“通用语言”模块化解决“代码复用与依赖管理”问题规范化解决“代码风格统一与质量可控”问题二者结合是多人协作的核心保障。重点掌握ES Module规范、CSS模块化和自动化代码校验。1. 模块化进阶ES Module深度实践ES ModuleESM是浏览器和Node.js原生支持的模块化规范替代CommonJS成为前端模块化主流重点掌握“动态导入”“模块联邦”等高级用法实战3ESM动态导入与代码分割通过动态导入实现“按需加载”减少首屏加载体积适用于路由组件、大型第三方组件如富文本编辑器// 1. 路由组件动态导入Vue Router import { createRouter, createWebHistory } from vue-router const routes [ { path: /, name: Home, component: () import(/views/Home.vue) // 动态导入单独打包 }, { path: /detail/:id, name: Detail, // 带加载状态的动态导入 component: () import(/* webpackChunkName: detail */ /views/Detail.vue) .then(component { return component }) .catch(error { // 加载失败处理 console.error(组件加载失败:, error) return import(/views/Error.vue) }) }, { path: /editor, name: Editor, // 路由懒加载权限控制 component: () { const hasPermission checkPermission() // 权限校验函数 if (hasPermission) { return import(/components/Editor/TinymceEditor.vue) } else { return import(/views/NoPermission.vue) } } } ] const router createRouter({ history: createWebHistory(), routes }) // 2. 工具函数动态导入按条件加载 async function loadUtils(type) { let utils switch (type) { case excel: // 加载Excel处理工具仅在需要时加载 utils await import(/utils/excelUtils.js) break case pdf: utils await import(/utils/pdfUtils.js) break default: utils await import(/utils/commonUtils.js) } return utils } // 3. 大型第三方库按需导入以lodash为例 // 不推荐全量导入 // import _ from lodash // 推荐按需导入配合tree-shaking import { debounce, throttle } from lodash-es // 动态导入特定功能 async function useLodashFunction(name) { const _ await import(lodash-es) return _.default[name] }实战4CSS模块化与样式隔离CSS模块化解决“样式污染”问题通过给类名添加唯一哈希值实现样式隔离适用于组件化开发场景!-- Vue组件中使用CSS模块化 -- template div classcontainer h2 :class$style.titleCSS模块化示例/h2 div :class[$style.card, $style.active] 模块化样式卡片 /div !-- 全局样式与模块化样式结合 -- div :class[$style.btn, global-btn] 混合样式按钮 /div /div /template script setup // 导入CSS模块指定module属性 import styles from ./ModuleStyle.module.scss // 或使用自动导入Vue3Vite // import ./ModuleStyle.module.scss /script style module langscss // 模块化样式类名会被编译为唯一哈希值 .container { padding: 20px; } .title { font-size: 24px; color: #333; margin-bottom: 20px; } .card { padding: 16px; border: 1px solid #eee; border-radius: 8px; transition: all 0.3s; .active { border-color: #1677ff; box-shadow: 0 2px 8px rgba(22, 119, 255, 0.1); } } .btn { padding: 8px 16px; border-radius: 4px; border: none; cursor: pointer; } /style style /* 全局样式 */ .global-btn { background-color: #1677ff; color: #fff; } /style// Vite中配置CSS模块化vite.config.js export default defineConfig({ css: { modules: { // 配置类名格式localName为原类名hash为哈希值 localsConvention: camelCaseOnly, // 类名转为驼峰式如card-active → cardActive generateScopedName: [name]__[local]__[hash:base64:5], // 自定义类名格式 hashPrefix: module, // 哈希前缀 globalModulePaths: [/global/], // 匹配global关键词的样式文件不进行模块化 } } })2. 规范化自动化代码校验与格式化通过ESLint、Prettier、Husky实现“代码校验-格式化-提交拦截”全流程规范化确保团队代码风格统一实战5ESLintPrettier配置代码质量与格式统一// 1. 安装依赖 // npm install eslint prettier eslint-plugin-vue eslint-config-prettier eslint-plugin-prettier vue/eslint-config-airbnb-base -D // 2. ESLint配置文件.eslintrc.js module.exports { root: true, env: { browser: true, es2021: true, node: true }, // 解析器配置 parser: vue-eslint-parser, parserOptions: { parser: babel/eslint-parser, ecmaVersion: latest, sourceType: module }, // 继承规则 extends: [ plugin:vue/vue3-essential, // Vue3基础规则 eslint-config-airbnb-base, // Airbnb基础规则 plugin:prettier/recommended // 整合Prettier优先Prettier规则 ], // 自定义规则 rules: { // 关闭强制使用函数声明的规则 func-style: off, // 允许console开发环境 no-console: process.env.NODE_ENV production ? warn : off, // 允许debugger开发环境 no-debugger: process.env.NODE_ENV production ? warn : off, // Vue规则允许单文件组件的setup语法糖 vue/setup-compiler-macros: error, // 关闭禁止使用下划线开头的变量 no-underscore-dangle: off, // 强制使用单引号 quotes: [error, single], // 强制不使用分号结尾 semi: [error, never] }, // 忽略文件 ignorePatterns: [node_modules/, dist/, public/] } // 3. Prettier配置文件.prettierrc.js module.exports { printWidth: 120, // 每行最大长度 tabWidth: 2, // 缩进宽度 useTabs: false, // 使用空格缩进 singleQuote: true, // 使用单引号 semi: false, // 不使用分号结尾 trailingComma: none, // 不使用尾随逗号 bracketSpacing: true, // 括号前后加空格 arrowParens: avoid, // 箭头函数单个参数时省略括号 vueIndentScriptAndStyle: true, // Vue文件中脚本和样式缩进 endOfLine: auto // 自动处理换行符 } // 4. 忽略文件.eslintignore .prettierignore node_modules/ dist/ public/ *.config.js *.json实战6Huskylint-staged配置提交拦截通过Husky监听Git提交钩子使用lint-staged只校验提交的文件提升效率并强制规范落地# 1. 安装依赖 # npm install husky lint-staged -D # 2. 初始化Huskypackage.json中添加脚本 { scripts: { prepare: husky install // 安装依赖后自动初始化Husky } } # 3. 执行初始化命令 # npm run prepare # 4. 添加pre-commit钩子提交前校验 # npx husky add .husky/pre-commit npx lint-staged # 5. 配置lint-stagedpackage.json中添加 { lint-staged: { *.{vue,js}: [ eslint --fix, // 自动修复ESLint错误 prettier --write // 自动格式化 ], *.{scss,css}: [ prettier --write // CSS/SCSS格式化 ], *.{json,md}: [ prettier --write // 其他文件格式化 ] } } # 6. 添加commit-msg钩子校验提交信息格式 # npx husky add .husky/commit-msg npx --no -- commitlint --edit $1 # 7. 安装commitlint依赖 # npm install commitlint/cli commitlint/config-conventional -D # 8. 配置commitlintcommitlint.config.js module.exports { extends: [commitlint/config-conventional] } # 提交信息格式要求type(scope): subject # 例如feat(home): 添加轮播图组件 # 例如fix(detail): 修复商品价格显示错误四、Day57自动化测试与部署——项目质量与交付保障自动化测试解决“手动测试低效”问题自动化部署解决“上线繁琐易出错”问题二者是项目稳定交付的核心保障。重点掌握单元测试、E2E测试和CI/CD流程搭建。1. 自动化测试从“单元测试”到“E2E测试”前端测试分为“单元测试”测试单个组件/函数、“组件测试”测试组件交互和“E2E测试”测试完整业务流程按需选择测试方案实战7JestVue Test Utils单元测试组件与函数测试Jest是前端主流测试框架配合Vue Test Utils实现Vue组件和工具函数的单元测试// 1. 安装依赖 // npm install jest vue/test-utils vue-jest babel-jest babel/core babel/preset-env -D // 2. 配置Jestjest.config.js module.exports { preset: vue/cli-plugin-unit-jest, // 模块文件扩展名 moduleFileExtensions: [vue, js, json, jsx, ts, tsx, node], // 模块别名 moduleNameMapper: { ^/(.*)$: rootDir/src/$1 }, // 转换器 transform: { ^.\\.vue$: vue-jest, ^.\\.js$: babel-jest }, // 测试环境 testEnvironment: jsdom, // 测试匹配规则 testMatch: [**/__tests__/**/*.[jt]s?(x), **/?(*.)(spec|test).[jt]s?(x)], // 覆盖率报告 collectCoverage: true, coverageDirectory: coverage, coverageReporters: [html, text-summary], // 忽略文件 coveragePathIgnorePatterns: [/node_modules/, /src/main.js, /src/router/] } // 3. 工具函数测试__tests__/utils/format.test.js import { formatPrice, formatDate } from /utils/format // 测试价格格式化函数 describe(formatPrice, () { test(格式化正数价格, () { expect(formatPrice(100)).toBe(¥100.00) expect(formatPrice(99.9)).toBe(¥99.90) expect(formatPrice(123.456)).toBe(¥123.46) }) test(格式化负数价格, () { expect(formatPrice(-50)).toBe(¥-50.00) }) test(处理空值和非数字, () { expect(formatPrice(null)).toBe(¥0.00) expect(formatPrice(undefined)).toBe(¥0.00) expect(formatPrice(abc)).toBe(¥0.00) }) }) // 测试日期格式化函数 describe(formatDate, () { test(格式化标准日期, () { const date new Date(2024-01-01 12:30:45) expect(formatDate(date)).toBe(2024-01-01) expect(formatDate(date, YYYY-MM-DD HH:mm:ss)).toBe(2024-01-01 12:30:45) }) test(处理时间戳, () { const timestamp 1704069045000 // 2024-01-01 12:30:45 expect(formatDate(timestamp)).toBe(2024-01-01) }) }) // 4. 组件测试__tests__/components/Button.test.js import { shallowMount } from vue/test-utils import MyButton from /components/MyButton.vue describe(MyButton组件, () { // 测试组件渲染 test(渲染默认按钮, () { const wrapper shallowMount(MyButton, { slots: { default: 默认按钮 } }) // 断言按钮文本正确 expect(wrapper.text()).toBe(默认按钮) // 断言按钮有默认类名 expect(wrapper.classes()).toContain(my-button) }) // 测试组件props test(根据type属性渲染不同样式, () { const wrapper shallowMount(MyButton, { props: { type: primary } }) expect(wrapper.classes()).toContain(my-button--primary) }) // 测试组件事件 test(点击按钮触发click事件, () { const wrapper shallowMount(MyButton) // 模拟点击 wrapper.trigger(click) // 断言事件被触发 expect(wrapper.emitted(click)).toBeTruthy() // 断言事件触发次数 expect(wrapper.emitted(click).length).toBe(1) }) // 测试禁用状态 test(禁用状态下不触发click事件, () { const wrapper shallowMount(MyButton, { props: { disabled: true } }) wrapper.trigger(click) // 断言事件未被触发 expect(wrapper.emitted(click)).toBeFalsy() // 断言有禁用类名 expect(wrapper.classes()).toContain(my-button--disabled) }) })实战8Cypress E2E测试完整业务流程测试Cypress是前端主流E2E测试工具模拟用户操作测试完整业务流程如“登录-添加商品-结算”// 1. 安装依赖 // npm install cypress -D // 2. 添加脚本package.json { scripts: { cypress:open: cypress open, // 打开Cypress可视化界面 cypress:run: cypress run // 执行E2E测试 } } // 3. 编写登录流程测试cypress/e2e/login.cy.js describe(登录流程测试, () { // 访问登录页 beforeEach(() { cy.visit(/login) // 访问登录页 }) // 测试正常登录 it(输入正确账号密码登录成功, () { // 输入账号 cy.get(input[nameusername]).type(testuser) // 输入密码 cy.get(input[namepassword]).type(test123456) // 点击登录按钮 cy.get(button[typesubmit]).click() // 断言登录成功后跳转到首页 cy.url().should(include, /home) // 断言首页显示用户名 cy.get(.user-name).should(contain, testuser) }) // 测试错误登录 it(输入错误密码登录失败, () { cy.get(input[nameusername]).type(testuser) cy.get(input[namepassword]).type(wrongpassword) cy.get(button[typesubmit]).click() // 断言显示错误提示 cy.get(.error-message).should(be.visible) cy.get(.error-message).should(contain, 账号或密码错误) // 断言未跳转 cy.url().should(include, /login) }) // 测试表单验证 it(未输入账号密码提示必填, () { cy.get(button[typesubmit]).click() // 断言账号必填提示 cy.get(input[nameusername]).siblings(.required-tip).should(be.visible) // 断言密码必填提示 cy.get(input[namepassword]).siblings(.required-tip).should(be.visible) }) }) // 4. 编写商品购买流程测试cypress/e2e/buy-goods.cy.js describe(商品购买流程测试, () { // 登录前置操作 beforeEach(() { // 登录使用fixture中的测试数据 cy.fixture(user).then(user { cy.visit(/login) cy.get(input[nameusername]).type(user.username) cy.get(input[namepassword]).type(user.password) cy.get(button[typesubmit]).click() }) }) it(完整购买流程浏览商品-添加购物车-结算, () { // 1. 浏览商品列表并进入详情页 cy.visit(/goods/list) cy.get(.goods-item).first().click() cy.url().should(include, /goods/detail) // 2. 选择商品数量并添加购物车 cy.get(.quantity-plus).click() // 数量1 cy.get(.quantity-input).should(have.value, 2) cy.get(.add-to-cart).click() // 断言添加成功提示 cy.get(.success-tip).should(contain, 已加入购物车) // 3. 进入购物车页面 cy.get(.cart-icon).click() cy.url().should(include, /cart) // 4. 勾选商品并结算 cy.get(.cart-item-checkbox).first().check() cy.get(.checkout-btn).click() cy.url().should(include, /checkout) // 5. 填写收货地址并提交订单 cy.get(.address-select).click() cy.get(.address-item).first().click() cy.get(.submit-order).click() // 断言订单提交成功 cy.url().should(include, /order/success) cy.get(.order-success-tip).should(contain, 订单提交成功) }) }) // 5. 测试数据文件cypress/fixtures/user.json { username: testuser, password: test123456 }2. 自动化部署CI/CD流程搭建GitHub Actions通过GitHub Actions实现“代码提交-自动测试-自动构建-自动部署”全流程自动化支持测试环境和生产环境部署# .github/workflows/ci-cd.yml name: 前端CI/CD流程 # 触发条件main分支和dev分支有push或pull_request时触发 on: push: branches: [ main, dev ] pull_request: branches: [ main, dev ] # 作业流程 jobs: # 1. 测试作业 test: runs-on: ubuntu-latest # 运行环境Ubuntu steps: # 步骤1拉取代码 - name: 拉取代码 uses: actions/checkoutv4 # 步骤2设置Node.js环境 - name: 设置Node.js uses: actions/setup-nodev4 with: node-version: 18 # Node.js版本 cache: npm # 缓存npm依赖 # 步骤3安装依赖 - name: 安装依赖 run: npm ci # 步骤4运行ESLint校验 - name: 代码校验 run: npm run lint # 步骤5运行单元测试 - name: 单元测试 run: npm run test:unit # 步骤6运行E2E测试仅在dev分支触发 - name: E2E测试 if: github.ref refs/heads/dev run: npm run test:e2e # 2. 构建作业依赖test作业成功 build: needs: test # 依赖test作业 runs-on: ubuntu-latest # 根据分支判断部署环境 env: ENV: ${{ github.ref refs/heads/main ? production : development }} steps: - name: 拉取代码 uses: actions/checkoutv4 - name: 设置Node.js uses: actions/setup-nodev4 with: node-version: 18 cache: npm - name: 安装依赖 run: npm ci - name: 构建项目 run: npm run build:${{ env.ENV }} # 根据环境构建 env: # 传递环境变量从GitHub Secrets中获取 VITE_API_BASE_URL: ${{ secrets[format(VITE_API_BASE_URL_{0}, env.ENV)] }} VITE_BASE_URL: ${{ secrets[format(VITE_BASE_URL_{0}, env.ENV)] }} # 步骤保存构建产物用于部署 - name: 保存构建产物 uses: actions/upload-artifactv4 with: name: dist-${{ env.ENV }} path: dist/ # 构建产物目录 # 3. 部署作业依赖build作业成功仅在push时触发 deploy: needs: build if: github.event_name push # 仅在push时触发 runs-on: ubuntu-latest env: ENV: ${{ github.ref refs/heads/main ? production : development }} steps: # 步骤1下载构建产物 - name: 下载构建产物 uses: actions/download-artifactv4 with: name: dist-${{ env.ENV }} path: dist/ # 步骤2部署到服务器以阿里云OSS为例 - name: 部署到阿里云OSS uses: manyuanrong/setup-ossutilv2 with: endpoint: ${{ secrets.OSS_ENDPOINT }} access-key-id: ${{ secrets.OSS_ACCESS_KEY_ID }} access-key-secret: ${{ secrets.OSS_ACCESS_KEY_SECRET }} # 步骤3上传文件到OSS - name: 上传文件 run: | ossutil cp -r dist/ oss://${{ secrets[format(OSS_BUCKET_{0}, env.ENV)] }}/ --delete # 覆盖上传并删除旧文件 # 步骤4刷新CDN生产环境 - name: 刷新CDN if: github.ref refs/heads/main run: | ossutil cdn-refresh -r ${{ secrets.VITE_BASE_URL_PRODUCTION }}* # 刷新CDN缓存 # 步骤5发送部署通知企业微信 - name: 发送部署通知 uses: actions-cool/wechat-work-notifyv2 with: key: ${{ secrets.WECHAT_WORK_KEY }} msgtype: markdown markdown: | # 前端部署通知 - 环境${{ env.ENV production ? 生产环境 : 测试环境 }} - 分支${{ github.ref_name }} - 提交人${{ github.actor }} - 提交信息${{ github.event.head_commit.message }} - 部署时间${{ github.event.repository.updated_at }} - 访问地址[点击访问](${{ secrets[format(VITE_BASE_URL_{0}, env.ENV)] }})五、总结与职场提升指南前端工程化是“规模化”开发的核心保障重点需掌握“构建工具优化-模块化规范-自动化测试-自动化部署”全流程。职场提升建议工具选型新项目优先用ViteESM提升效率大型项目用Webpack代码分割优化性能规范落地通过ESLintPrettierHusky强制规范减少协作成本测试策略核心工具函数100%单元测试覆盖关键业务流程做E2E测试持续优化定期通过构建体积分析工具visualizer优化包体积通过监控工具收集性能数据。下一篇将聚焦前端性能优化进阶从“加载性能”“渲染性能”“运行时性能”三个维度结合实战案例讲解性能优化的核心技巧。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

怎么做网站代理网站为什么维护

还在为B站视频无法离线观看而烦恼?想要建立属于自己的媒体资料库?哔哩下载姬DownKyi将为你开启全新的视频管理体验,让精彩内容随时随地触手可及! 【免费下载链接】downkyi 哔哩下载姬downkyi,哔哩哔哩网站视频下载工具…

张小明 2025/12/23 17:16:44 网站建设

龙岗附近公司做网站建设多少钱织梦 响应式网站

Font Awesome 7全面解析:现代化图标解决方案的革新之路 【免费下载链接】Font-Awesome The iconic SVG, font, and CSS toolkit 项目地址: https://gitcode.com/GitHub_Trending/fo/Font-Awesome 在当今快速发展的前端开发领域,图标作为用户界面的…

张小明 2025/12/24 3:14:46 网站建设

建设网站的报价h5 技术做健康类网站

KlipperScreen触摸屏界面终极安装完整指南 【免费下载链接】KlipperScreen GUI for Klipper 项目地址: https://gitcode.com/gh_mirrors/kl/KlipperScreen KlipperScreen是一款专为Klipper 3D打印机设计的触摸屏图形用户界面,通过与Moonraker API服务器通信&…

张小明 2025/12/23 19:41:28 网站建设

网站开发项目的设计与实现网页设计素材 百度云

2025年11月11日,人工智能领域迎来重大技术革新——CogVLM2多模态大模型家族正式开源。作为基于Meta-Llama-3-8B-Instruct架构开发的新一代基础模型,该系列凭借三大核心突破重新定义了开源多模态技术标准:8K tokens超长文本处理能力实现万字级…

张小明 2025/12/23 14:11:13 网站建设