当前位置: 首页 > news >正文

长春网站建设吉网传媒实力牜注册网站需要什么程序

长春网站建设吉网传媒实力牜,注册网站需要什么程序,个人网站创建平台要多少钱,广告网页前言 在前端开发过程中#xff0c;常常面对多种业务场景。到目前为止#xff0c;前端对于不同场景的处理通常会采用不同的渲染方案来组合处理#xff0c;常见的渲染方案包括#xff1a;CSR(Client Side Rendering)、SSR(Server Side Rendering)、SSG(Static Site Generati… 前言 在前端开发过程中常常面对多种业务场景。到目前为止前端对于不同场景的处理通常会采用不同的渲染方案来组合处理常见的渲染方案包括CSR(Client Side Rendering)、SSR(Server Side Rendering)、SSG(Static Site Generation)、ISR(Incremental Site Rendering)、DPR(Distributed Persistent Rendering)、NSR(Native Side Rendering)以及ESR(Edge Side Rendering)等。在目前项目开发过程中遇到了需要构建门户类应用的需求而团队主要技术栈以Vue为主整个技术方案以Vue全家桶进行构建。因此本文旨在针对门户类应用的场景下的Vue脚手架构建方案的一些总结和分析通过自动化的配置脚本来生成模板化的多页应用实践以期能够给读者提供一个基于Vue全家桶的门户类工程构建方案。 架构 对于门户类型的应用由于其大部分内容变动内容较少而对于部分关键页面却会有动态更新的要求因而在通常会采用多页形式的处理配合部分单页应用中的优势进行处理。因而在技术选型方面团队采用了预渲染配合多页的方式实现门户类SEO及首屏加载快的需求。同时结合单页应用的优势在多页中的部分关键页面中采用单页中的优点如路由切换快、用户体验好等。综上架构风格采用ISR的增量渲染方案由于项目背景的特殊性无法配合常规CDN等部署方案特点但可以使用云原生相关的中间件实现类似效果整体部署仍以“云端”的形式为主。 目录 selfService├─portal ├─ build // vue cli打包所需的options中内容一些抽离对其中做了环境区分 | ├─ demo | | ├─config.json | | ├─configureWebpack.js | ├─ dev | | ├─ config.json | | ├─ configureWebpack.js | ├─ production | | ├─ config.json | | ├─ configureWebpack.js | ├─ chainWebpack.js | ├─ configureWebpack.js | ├─ devServer.js | ├─ pages.js | ├─ routes.js | ├─ index.js | ├─ utils.js ├─ deploy // 不同环境的部署 | ├─ demo | | ├─ default.conf | | ├─ Dockerfile | | ├─ env.sh | ├─ dev | | ├─ default.conf | | ├─ Dockerfile | | ├─ env.sh | ├─ production | | ├─ default.conf | | ├─ Dockerfile | | ├─ env.sh | ├─ build.sh ├─ public | ├─ pageA // pageA的html这里可以存放一些静态资源非构建状态下的js、css等 | | ├─ index.html | ├─ pageB // pageB的html这里可以存放一些静态资源非构建状态下的js、css等 | | ├─ index.html | ├─ favicon.ico ├─ src | ├─ assets // 存放小资源通常为必须如logo等其他静态资源请放入cdn或者public下 | | ├─ logo.png | ├─ components // 公共组件可抽离多个静态页面的公共组件 | | ├─ Header.vue | ├─ router | | ├─ pageA // pageA的router使用了history模式 | | ├─ index.js | | ├─ pageB // pageB的router使用了history模式 | | ├─ index.js | ├─ store | | ├─ pageA // pageA的Vuex | | ├─ index.js | | ├─ pageB // pageB的Vuex | | ├─ index.js | ├─ views | | ├─ pageA // pageA的页面写法和之前一个的单页应用一致 | | ├─ main.js // 注入了mode挂载到了vue的原型上使用this可以获取环境变量 | | ├─ pageA.vue | | ├─ pageB // pageB的页面写法和之前一个的单页应用一致 | | ├─ main.js // 注入了mode挂载到了vue的原型上使用this可以获取环境变量 | | ├─ pageB.vue ├─ scripts ├─ babel.config.js // 配置es转化语法 ├─ vue.config.js // vue cli打包相关配置 ├─ app.json // 存放各个多页应用的public、router、vuex、views入口地址实践 配置 Vue脚手架中配置多页主要是使用Webpack中的pages入口配置这里主要是修改vue.config.js中的pages的设置代码如下 const PrerenderSPAPlugin require(prerender-spa-plugin); const Renderer PrerenderSPAPlugin.PuppeteerRenderer; module.exports {// ...pages: {page3:{entry: src/views/page3/main.js,template: public/page3/index.html,filename: page3.html,title: page3}},configureWebpack: config {config.plugins.push(new PrerenderSPAPlugin({staticDir: path.resolve(__dirname,../../dist),routes: [/page3],renderer: new Renderer({less: false,//renderAfterDocumentEvent: render-event,//renderAfterTime: 5000,//renderAfterElementExists: my-app-element}),}))} }其中如果配置了pagesvue/cli-service会先清除原有的entry如果没有index则devServer默认入口的根路径’/‘仍为index.html如果有index的key值则会进行相应的覆盖。在这里对pages下的key值为对应多页的路径如上述代码下的page3则对应的路径为’/page3.html’pages下的value可以为字符串也可以为对象其中entry为多页的入口必选项、template为模板来源、filename为打包后的输出名称以及title会通过html-webpack-plugin的插件对template中的title% htmlWebpackPlugin.options.title %/title进行替换。 而对于预渲染的应用这里使用了prerender-spa-plugin和vue-meta-info来进行SEO及首屏加载优化代码如下 // ... import MetaInfo from vue-meta-infoVue.use(MetaInfo)new Vue({router,store,render: h h(index),mounted () {document.dispatchEvent(new Event(custom-render-trigger))} }).$mount(#page3)脚本 通过上述的配置基本就可以实现一个 预渲染多页 的vue脚手架搭建。但是除了开发环境的配置对于生产环境、部署等也需要进行一定的设置这样频繁的操作就会带来一定的功效降低。因而在前端工程化领域中通常会进行一定的脚本化或者说脚手架方案的构建。这里在目前项目中团队对多页应用的配置进行了自动化的脚本实现。 生成多页的脚本主要通过page.js进行实现代码如下 const inquirer require(inquirer); const chalk require(chalk); const fs require(fs); const path require(path); const ora require(ora); const { transform, compose } require(./utils);const spinner ora();const PAGE_REG /[a-zA-Z_0-9]/ig; const rootDir path.resolve(process.cwd(), .);// 判断dir目录下是否存在name的文件夹 const isExt (dir, name) fs.existsSync(path.join(dir, name));const APP_JSON_EJS {pages: % page_name % };const INDEX_HTML_EJS !DOCTYPE html html langheadmeta charsetutf-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width,initial-scale1.0link relicon href../favicon.icotitle% htmlWebpackPlugin.options.title %/title/headbodynoscriptstrongWere sorry but % htmlWebpackPlugin.options.title % doesnt work properly without JavaScript enabled. Please enable it to continue./strong/noscript% page_name %/body /html const INDEX_VUE_EJS % page_name %script export default { components: { }, data() {return {}; }, }; /scriptstyle langless /styleconst MAIN_JS_EJS % page_name %const INDEX_ROUTER_EJS import Vue from vue import VueRouter from vue-routerVue.use(VueRouter)const routes [% page_name % ]const router new VueRouter({mode: history,routes })export default routerconst INDEX_STORE_EJS import Vue from vue import Vuex from vuexVue.use(Vuex)export default new Vuex.Store({state: {},mutations: {},actions: {},modules: {} }) // inquirer list const promptList [{type: input,name: page_name,message: 请输入你想要创建的多页应用名称,filter: function (v) {return v.match(PAGE_REG).join()}} ];// nginx的default.conf所需添加内容 const addDefaultConf page_name {return location /${page_name} {root /usr/share/nginx/html;index ${page_name}.html;try_files $uri $uri/ /${page_name}.html;gzip_static on; } };// page_name下的index.html const addIndexHtml page_name {return div id${page_name} data-server-renderedtrue/div };// page_name下的router const addRouterIndex page_name {return {path: /,component: () import(../../views/${page_name}/index.vue) }, };// page_name下的views index.vue const addViewsIndex page_name {return templatediv${page_name}/div /template };// page_name下的views main.js const addViewsMain page_name {return import Vue from vue import index from ./index.vue import router from ../../router/${page_name}/index.js import store from ../../store/${page_name}/index.js import MetaInfo from vue-meta-infoVue.use(MetaInfo)import axios from axiosVue.prototype.$mode process.env.VUE_APP_MODE;Vue.prototype.axios axios;Vue.config.productionTip falsenew Vue({router,store,render: h h(index),mounted () {document.dispatchEvent(new Event(custom-render-trigger))} }).$mount(#${page_name}) };// page_name下的pages.js const addPages page_name {return JSON.stringify({entry: src/views/${page_name}/main.js,template: public/${page_name}/index.html,filename: ${page_name}.html,title: ${page_name},}) }const updateApp page_name {// 获取pages的数组const pages require(../app.json)[pages];if(pages.includes(page_name)) return true;pages.push(page_name);spinner.start()fs.writeFile(${rootDir}/app.json, transform(/% page_name %/g, JSON.stringify(pages), APP_JSON_EJS), err {spinner.color red;spinner.text Loading Update app.jsonif(err) {spinner.fail(chalk.red(更新app.json失败))return false;} else {spinner.succeed(chalk.green(更新app.json成功))return true;}}); }// 处理 public 文件夹下的核心逻辑 const processPublic args {const { page_name } args;if(isExt(${rootDir}/public, page_name)) {return args;} else {fs.mkdirSync(${rootDir}/public/${page_name})}fs.writeFileSync(${rootDir}/public/${page_name}/index.html, transform(/% page_name %/g, addIndexHtml(page_name), INDEX_HTML_EJS));// 处理默认页面的跳转const content require(../app.json)[pages].map(page {return lia href/${page}.html${page}/a /li}).join( );const ejs_arr fs.readFileSync(${rootDir}/public/index.html, utf-8).split(body);fs.writeFileSync(${rootDir}/public/index.html, ejs_arr[0] body h1自服务门户/h1 ul${content} /ul /body /html);return args; };// 处理 src/views 文件夹下的核心逻辑 const processViews args {const { page_name } args;if(isExt(${rootDir}/src/views, page_name)) {return args;} else {fs.mkdirSync(${rootDir}/src/views/${page_name})}fs.writeFileSync(${rootDir}/src/views/${page_name}/index.vue, transform(/% page_name %/g, addViewsIndex(page_name), INDEX_VUE_EJS));fs.writeFileSync(${rootDir}/src/views/${page_name}/main.js, transform(/% page_name %/g, addViewsMain(page_name), MAIN_JS_EJS));return args; };// 处理 src/router 文件夹下的核心逻辑 const processRouter args {const { page_name } args;if(isExt(${rootDir}/src/router, page_name)) {return args;} else {fs.mkdirSync(${rootDir}/src/router/${page_name})}fs.writeFileSync(${rootDir}/src/router/${page_name}/index.js, transform(/% page_name %/g, addRouterIndex(page_name), INDEX_ROUTER_EJS));return args; };// 处理 src/store 文件夹下的核心逻辑 const processStore args {const { page_name } args;if(isExt(${rootDir}/src/store, page_name)) {return args;} else {fs.mkdirSync(${rootDir}/src/store/${page_name})}fs.writeFileSync(${rootDir}/src/store/${page_name}/index.js, INDEX_STORE_EJS);return args; };// 处理 build 文件夹下的核心逻辑 const processBuild args {const { page_name } args;// 处理 build/page.jsconst pages require(../build/pages.js);if(Object.keys(pages).includes(page_name)) return args;pages[${page_name}] JSON.parse(addPages(page_name));const PAGES_JS_EJS const pages ${JSON.stringify(pages)} module.exports pages;;fs.writeFileSync(${rootDir}/build/pages.js, PAGES_JS_EJS);// 处理 build/routes.jsconst routes require(../build/routes.js);if(routes.includes(/${page_name})) return args;routes.push(/${page_name});const ROUTES_JS_EJS const pages ${JSON.stringify(routes)} module.exports pages;;fs.writeFileSync(${rootDir}/build/routes.js, ROUTES_JS_EJS);return args; }// 处理 deploy 文件夹下的核心逻辑 const processDeploy args {const { page_name } args;const reg new RegExp(location /${page_name});[demo, dev, production].forEach(item {const content fs.readFileSync(${rootDir}/deploy/${item}/default.conf, utf-8);if(reg.test(content)) return args;const ejs_arr content.split(location /api/)fs.writeFileSync(${rootDir}/deploy/${item}/default.conf, transform(/% page_name %/g, addDefaultConf(page_name), ejs_arr[0] % page_name % location /api/ ejs_arr[1]));});return args; };inquirer.prompt(promptList).then(answers {const page_name answers.page_name;return updateApp(page_name)}).then(() {const pages require(../app.json)[pages];pages.forEach(page {console.log(page, page)compose(processDeploy,processBuild, processStore, processRouter, processViews, processPublic)({page_name: page});})}).catch(err {if(err) {console.log(chalk.red(err))}})为了更好的实现代码的优雅性对代码工具进行了抽离放入到utils.js中代码如下 // 将内容替换进ejs占位符 const transform ($, content, ejs) ejs.replace($,content);// 将流程串联 const compose (...args) args.reduce((prev,current) (...values) prev(current(...values)));module.exports {transform,compose }总结 仅管到目前为止单页应用仍是前端开发中的主流方案。但是随着各大应用的复杂度提升多种方案的建设也都有了来自业界不同的声音诸如多种渲染方案、Island架构等都是为了能更好的提升Web领域的体验与开发建设。技术方案的选择不只局限于生态的整合更重要的是对合适场景的合理应用。 “形而上者谓之道,形而下者谓之器”各位前端开发者不仅应该只着眼于眼前的业务实现同时也需要展望未来站在更高的视野上来俯视技术的走向与演进共勉 参考 vue-cli搭建自动化多页面项目vue高阶Vue-cli配置多页面vue预渲染之prerender-spa-plugin插件应用预渲染插件prerender-spa-plugin生成多页面CSR、SSR、NSR、ESR傻傻分不清楚一文帮你理清前端渲染方案vue项目改造SSR服务端渲染什么是SSR/SSG/ISR如何在AWS上托管它们卷起来前端建站SSGSSRISRHydration, Island…一网打尽你知道吗SSR、SSG、ISR、DPR 有什么区别SSR、ISR、CSR、SSG有什么区别一文看懂Next.js渲染方法CSR、SSR、SSG和ISR
http://www.hkea.cn/news/14324726/

相关文章:

  • 西安网站建设德阳seo优化
  • 南宁企业门户网站建设价格关键词有哪些
  • 成都j网站制作厦门建设官网
  • 做网站的计划wordpress 4.6.11
  • 提示网站建设页面企业型网站制作
  • 东营市东营网站设计广东住房和城乡建设厅网站造价
  • wordpress前端开发河北百度seo关键词
  • 微信公众平台如何与wordpress对接实现自动回复功能资阳优化团队平台
  • 江门企业做网站广东网站建设
  • pc站转换手机网站网站推广途径有哪些
  • 如何看网站空间问题助贷获客系统
  • 网站下载的网页修改下面版权所有网站优化北京联系电话?
  • 松滋网站开发黄页企业名录
  • 精品简历模板网站工装装修
  • 信用网站建设意见宝应网页设计
  • 遵义网站制作小程序化州网站建设公司
  • 常州市建设工程质监站网站wordpress评论修改
  • 企业网站是企业在互联网上进行网络营销做维修电器网站
  • 局网站建设管理制度台中网站建设
  • 江西专业的网站建设公司在俄罗斯用钱让女性做h事情的网站
  • 昆山app网站制作自动提卡的网站怎么做的
  • 怎么做网页投票整站优化与关键词排名
  • tomcat 怎么做网站装饰装修网站大全
  • 纯静态网站开发公司网站建设知乎
  • 江苏建设人才网网站做房产网站怎么样
  • 微信公众号开发网站开发做ppt网站大全
  • 做网站的素材都在哪里下载互联网编程培训
  • 网站开发服务wordpress固定链接设置.html
  • 容易被收录的网站人才招聘类网站开发文档
  • 一个空间安装多个网站百度网站关键词优化