{"id":16439919,"url":"https://github.com/meckodo/vue-multipage","last_synced_at":"2025-04-09T22:19:05.994Z","repository":{"id":127703730,"uuid":"67114140","full_name":"MeCKodo/vue-multipage","owner":"MeCKodo","description":"fuck multipage","archived":false,"fork":false,"pushed_at":"2017-08-31T03:59:37.000Z","size":651,"stargazers_count":300,"open_issues_count":9,"forks_count":65,"subscribers_count":27,"default_branch":"master","last_synced_at":"2025-04-09T22:19:00.441Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MeCKodo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-01T08:43:22.000Z","updated_at":"2025-02-26T04:20:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"a6828996-2dba-4bfd-9b7b-5b4e1a276629","html_url":"https://github.com/MeCKodo/vue-multipage","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MeCKodo%2Fvue-multipage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MeCKodo%2Fvue-multipage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MeCKodo%2Fvue-multipage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MeCKodo%2Fvue-multipage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MeCKodo","download_url":"https://codeload.github.com/MeCKodo/vue-multipage/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248119283,"owners_count":21050755,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T09:10:42.858Z","updated_at":"2025-04-09T22:19:05.967Z","avatar_url":"https://github.com/MeCKodo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vue或React多页应用脚手架\n\u003e 已升级2.0版本,优化目录结构,内部构建机制都换了  2016年11月01日\n\n\u003e 升级3.0版本，优化目录结构，优化编译速度,webpack替换为3.X  2017年08月31日\n---\n\n## 前言\n\n\u003e 一直以来都在研究多页应用如何能有一套像SPA一样优雅的开发模式\n\n\u003e 本套架构在项目上使用感觉还不错（已跑在上百个页面的项目上），所以决定开源出来给大家\n\n\u003e 阅读完本文能实现在项目中使用ES6(7)+组件化（.vue | .jsx）开发多页应用\n\n\u003e (其实我是想把它做为大家多页应用的脚手架)\n\n\n## 目录结构介绍\n\n\u003e TIPS：任何的项目的架构都和目录结构有关，所以这部分非常重要，请仔细耐心阅读\n\n我们先宏观的看下结构\n\n```js\n|--- public // 生产环境下所需的文件\n    |--- components\n\t|--- css\n\t|--- fonts\n\t|--- images\n\t|--- js\n\t|--- sass\n\t|--- views\n|--- src\n    |--- components\n    |--- css\n\t|--- fonts\n\t|--- images\n    |--- js\n    |--- sass\n    |--- views\n```\n\n---\n\n我们展开介绍下具体的页面应该如何对应它的资源。拿`js`和`views`为例\n\n```js\n|--- views\n    |--- home // 官网介绍 业务模块\n        |--- index.html\n        ...\n    |--- shopping // 购物业务模块\n        |--- buy.html\n        ...\n|--- js\n    |--- lib\n        |--- vue.js\n        |--- react.js\n        |--- react.dom.js\n        ...\n    |--- home // 官网介绍业务模块的js\n        |--- index.js\n        ...\n    |--- shopping // 购物业务模块的js\n        |--- buy.js\n        ...\n    tools.js\n    common.js\n```\n\n在多页应用中，往往我们的页面以业务模块划分，业务模块由许多的页面组成。\n如`home，shopping`，可能就分别为官网介绍和购物的业务模块。在这业务模块下，分别有许多个页面，那我们的js文件也需要命名一一对应。\n\n当然，我们还有第三方的js库是不需要编译的，所以我们专门用一个`lib`文件夹来存放他们。(包括你自己编写的指令或者filter等，不需要编译的，也直接放在lib下引入即可)\n\n另外，你还有许多自己写的需要编译的工具库直接放在`js`目录下即可(如，tools.js,common.js)\n\n---\n\n我们的sass也是同理\n\n```js\n|--- sass\n    |--- home\n        |--- index.scss\n        ...\n    |--- shopping\n        |--- buy.scss\n        ...\n```\n\n页面引用的路径就为(home/index.html为例)\n\n```js\n...\n\u003clink rel=\"stylesheet\" href=\"../../css/home/index.css\"\u003e\n\n...\n\n\u003cscript src=\"../../js/lib/vue(react).js\"\u003e\u003c/script\u003e\n\u003cscript src=\"../../js/lib/react.dom.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"../../js/home/index.js\"\u003e\u003c/script\u003e\n...\n```\n\n---\n\njs和sass搞定了后，我们的难点是编写组件的过程中，如何知道应该编译哪个入口js文件呢？\n所以我们需要对我们的组件名进行一些约定，这也就是约定大于配置的前提。\n\n```js\n|--- components\n    |--- home // home 业务模块\n        |--- home-header.vue(jsx)\n        |--- index-info.vue(jsx)\n        ...\n    |--- shopping  // shopping 业务模块\n        |--- buy-list.vue(jsx)\n        ...\n```\n\n我们`components`下的业务模块名和之前的sass，js一样。具体组件那就有所不同。\n\n我们分为几种类型的组件\n\u003e *  一、当前页面使用的组件\n\u003e *  二、当前业务模块下的公用组件\n\u003e *  三、所有业务模块的通用组件\n\n当前页面组件的命名，我们约定为  `[页面]-[组件].vue(jsx)`\n\n如下\n```js\n|--- components\n    |--- home\n        |--- index-info.vue(jsx)\n```\n这个`index-info`的组件就仅仅只有在`home/index.html`页面下使用，当你修改了这个组件后，会自动编译`home/index.js`路口js文件并刷新页面。\n\n\n当前业务模块下的公用组件，我们约定为 `[业务模块]-[组件].vue(jsx)`\n\n如下\n```js\n|--- components\n    |--- home\n        |--- home-header.vue(jsx)\n```\n\n这个`home-header`组件就属于`home`业务模块下的公用组件，当你修改了这个组件后，会自动编译`home`业务模块下所有的js文件并刷新页面。\n\n剩下的就是所有业务模块下的通用组件，我们约定全放在`components/common`目录下，不需要具体命名约定\n\n```js\n|--- components\n    |--- common\n        |--- loading.vue(jsx)\n```\n这个`loading`组件就属于所有业务模块下的公用组件，当你修改了这个组件后，会自动编译所有业务模块下的js文件并刷新页面。\n\n编译组件的原理以及为什么约定命名的原因是：\n\n\u003e 我会根据组件更改变动，去读取文件夹名，组件名，并编译对应名的路口js\n\n至此，我们就把组件的问题也解决了\n\n由于我采用的是主gulp辅webpack，webpack仅仅只编译用，所以编译基本达到秒编译。比单纯利用webpack做构建快得多。如果单纯采用webpack做构建，需要去配置entry，配置HTMLPlugin。所以会慢得多，然而我这一套并不需要如此繁琐。\n\n## 图片\u0026\u0026字体文件\n\n\u003e 这其实是一个大坑\n\n我们的实现目标是**组件能相对路径引入图片或字体文件**\n\n```js\n// 如 在html标签里这样\n\u003ctemplate\u003e\n\t\u003cfigure\u003e\n\t\t\u003cimg src=\"../../assets/images/home/logo.jpg\" alt=\"头像\"\u003e\n\t\u003c/figure\u003e\n\u003c/template\u003e\n\n// 在style里这样\n\u003cstyle rel=\"stylesheet/scss\" lang=\"sass\"\u003e\n\t@import \"../../sass/home/index-info\";\n\t// 甚至可能在这@import面引入相对路径，这都会算是在组件里引入相对路径\n    #bg h3 {\n\t\tbackground: url(\"../../assets/images/holmes.jpg\");\n\t\tcolor: #fff;\n\t}\n\u003c/style\u003e\n```\n\n这个坑，真是**不可描述**，我个人尝试了各种体位，才把这个坑配置好。\n\n直接给大家看最后实现是怎样的。\n\n\u003e `dev` 的路径是这样，页面可以显示图片或字体。\n\n![](http://7xt8eu.com1.z0.glb.clouddn.com/multpage-5.png)\n\n\u003e`build` 后的路径是这样\n\n![](http://7xt8eu.com1.z0.glb.clouddn.com/mulupage-6.png)\n\n这样就达到了开发和发布后的资源统一，摸索这一步真是挺累的 T.T，有兴趣的自己看源码吧。\n\n## 环境变量的配置\n\n\u003e 我们在webpack中经常会遇见不同环境下不同配置的问题\n\n首先可在`package.json`里配置一条`script`\n\n```js\n// package.json\n\"scripts\": {\n    \"build\": \"NODE_ENV=production gulp build\",\n    \"dev\": \"NODE_ENV=dev gulp reload\"\n},\n```\n\n假设我们需要为不同环境配置不同的api请求地址,就可以利用我们在`package.json`设置的`NODE_ENV`来识别当前环境(这部分我在gulpfile中处理了，所以在文件里可直接识别NODE_ENV，如下)\n\n```js\n//  src/js/ajaxurl.js\n \nconst server1 = 'https://production.server.com';\nconst server2 = 'https://dev.server.com';\n\nlet useServer = null;\nif(NODE_ENV === 'production') {\n\tuseServer = server1;\n} else if(NODE_ENV === 'dev') {\n\tuseServer = server2;\n}\n\nexport default useServer;\n```\n\n```js\n// src/js/home/index.js\n\nimport url from '../ajaxurl';\nconsole.log(url);\n```\n\n这样就解决了我们不同环境下不同配置的问题，我默认配置了`dev`和`production`，大家可以自行拓展。比如\n\n假设你需要在 **开发中** 配置测试，你可以写一条`NODE_ENV=test gulp reload`。\n\n如果需要 **预发布打包** 测试，就可以另一条`NODE_ENV=preproduction gulp build`。\n\n总之就是打包使用`gulp build`，开发使用`gulp reload`。\n\n## 注意事项\n\n开发：执行命令 `npm run dev`\n发布：执行命令 `npm run build` (BTW，别忘了去`gulpfile.js`里替换你的CDN链接，进入gulp文件修改 const CDN = 'yourCDNLink'这里的变量即可) \n\n命名一定要按约定来！\n命名一定要按约定来！\n命名一定要按约定来！\n\n否则不知道要编译谁！！！\n\ngulp配置很简单，大家可以看一下针对各自项目进行修改，不懂得可以直接问我。\n\n如果你们不完全的前后端分离，把这个src直接放在后台目录下也没有问题。\n\n写vue和react都没问题，我把示例demo都写好了，下面是分别两个的repo地址。\n\nvue-multpage : [https://github.com/MeCKodo/vue-multipage](https://github.com/MeCKodo/vue-multipage)\n\n## TODO\n\n- [ ] 项目的Unit test\n- [ ] 项目Cli脚手架\n\n## 后话\n\n本来是想写成`vue-cli`或者是`create-react-app`这种cli脚手架的，但是！本人真是太懒又没有时间了！ 各位看官可以先尝试clone把玩把玩，如果有足够多人喜欢，我就把他写成cli，发布npm :)\n\n我是用mac下开发完成的，用了半天多时间专门去给window写了兼容，window还可能会有bug，不是我说！**window就是辣鸡！**\n\n最后给大家看下我们的某项目结构。\n\n---\n\n**总览**\n![总览](http://7xt8eu.com1.z0.glb.clouddn.com/multpage-4.png)\n\n**js部分**\n![js部分](http://7xt8eu.com1.z0.glb.clouddn.com/multpage-1.png)\n\n**sass部分**\n![sass部分](http://7xt8eu.com1.z0.glb.clouddn.com/multpage-2.png)\n\n**组件和页面**\n![组件和页面](http://7xt8eu.com1.z0.glb.clouddn.com/multpage-3.png)\n\n\n---\nHave a nice day\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeckodo%2Fvue-multipage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeckodo%2Fvue-multipage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeckodo%2Fvue-multipage/lists"}