最近在使用 ThinkJS + vue2.0 写一个简单的项目, 该项目分为用户端和管理界面, 分别对应 vue 的两个页面 index 和 admin , 用户端, 管理界面自身是基于 vue 构建的单页应用, 服务端采用 thinkjs 的提供 api.
项目目录结构如下:
- .
- README.md
- client
- README.md
- build
- config
- package.json
- src
- components
- modules
- pages
- admin
- index
- static
- server
- src
- bootstrap
- config
- controller
- admin
- base.js
- home
- index.js
- logic
- model
- view
- admin.html
- index.html
- www
- static
client 的配置
直接使用 vue 官方的 https://github.com/vuejs/vue-cli 创建项目, 选择使用 webpack 构建.
修改 config/index.js , 给 webpack-dev-server 添加 proxyTable:
- proxyTable: {
- '/api' : {
- target: 'http://localhost:8360/api/',
- changeOrigin: true,
- pathRewrite: {'^/api': '/'}
- }
- },
然后参照 使用 Vue-cli 搭建多页面应用时对项目结构和配置的调整 https://www.jianshu.com/p/0a30aca71b16 的方法将其改为多页应用, 具体方法为:
调整项目目录, 创建 src/pages/index , 将 src/assets , src/router , src/App.vue , src/main.js 和 ./index.html 移动到该目录中, 并将 main.js 改名为 index.js .
修改构建脚本 build/utils.js , 添加:
- // glob 是 webpack 安装时依赖的一个第三方模块, 还模块允许你使用 * 等符号, 例如 lib/*.js 就是获取 lib 文件夹下的所有 js 后缀名的文件
- var glob = require('glob')
- // 页面模板
- var HtmlWebpackPlugin = require('html-webpack-plugin')
- // 取得相应的页面路径, 因为之前的配置, 所以是 src 文件夹下的 pages 文件夹
- var PAGE_PATH = path.resolve(__dirname, '../src/pages')
- // 用于做相应的 merge 处理
- var merge = require('webpack-merge')
- // 多入口配置
- // 通过 glob 模块读取 pages 文件夹下的所有对应文件夹下的 js 后缀文件, 如果该文件存在
- // 那么就作为入口处理
- exports.entries = function() {
- var entryFiles = glob.sync(PAGE_PATH + '/*/*.js')
- var map = {}
- entryFiles.forEach((filePath) => {
- var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
- map[filename] = filePath
- })
- return map
- }
- // 多页面输出配置
- // 与上面的多页面入口配置相同, 读取 pages 文件夹下的对应的 html 后缀文件, 然后放入数组中
- exports.htmlPlugin = function() {
- let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')
- return entryHtml.map((filePath) => {
- let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
- let conf = {
- // 模板来源
- template: filePath,
- // 文件名称
- filename: filename + '.html',
- // 页面模板需要加对应的 js 脚本, 如果不加这行则每个页面都会引入所有的 js 脚本
- chunks: ['manifest', 'vendor', filename],
- inject: true
- }
- if (process.env.NODE_ENV === 'production') {
- conf = merge(conf, {
- minify: {
- removeComments: true,
- collapseWhitespace: true,
- removeAttributeQuotes: true
- },
- chunksSortMode: 'dependency'
- })
- }
- return new HtmlWebpackPlugin(conf)
- })
- }
修改
build/webpack.base.conf.js
的入口配置:
- module.exports = {
- context: path.resolve(__dirname, '../'),
- entry: utils.entries(),
- ...
- ...
- }
修改
build/webpack.dev.conf.js
和
build/webpack.prod.conf.js
的插件配置:
- plugins: [
- ...
- // https://github.com/ampedandwired/html-webpack-plugin
- ...utils.htmlPlugin(),
- ...
- ]
创建 src/pages/admin 目录, 添加 admin.html 文件:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
- <body>
- <h1>Admin</h1>
- </body>
- </html>
创建 src/pages/404 目录, 添加 404.html 文件:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>404</title>
- </head>
- <body>
- <h1>404 Not Found</h1>
- </body>
- </html>
修改 webpack-dev-server 的路由表:
- historyApiFallback: {
- rewrites: [
- { from: /^\/$/, to: '/index.html' },
- { from: /^\/admin\/?$/, to: '/admin.html' },
- { from: /./, to: '/404.html' }
- ],
- },
至此 client 端的配置就完成了, 可以通过 npm start 启动 client 端, 通过
http://localhost:8080
访问页面.
server 的配置
直接使用 ThinkJS 官方的 https://github.com/thinkjs/think-cli 创建项目, 修改
src/config/router.js
, 添加路由:
- module.exports = [
- [/^\/api\/(.*)/i, '/:1'],
- [/^\/$/i, '/'],
- [/^\/admin\/?$/i, '/index/admin'],
- [/\//, 'index/_404', 'get']
- ];
修改
src/controller/index.js
渲染模板:
- const Base = require('./base.js');
- module.exports = class extends Base {
- indexAction() {
- return this.display('index.html');
- }
- adminAction() {
- return this.display('admin.html');
- }
- _404Action() {
- return this.display('404.html');
- }
- };
至此服务器的配置完成, 启动 server 端, client 可通过
http://localhost:8080/api
访问 API.
开发服务端 API
在 server 中任意 controller 暴露的 API 可以通过
/api/controller/action
来访问, 比如:
- // src/controller/test.js
- const Base = require('./base.js');
- module.exports = class extends Base {
- indexAction() {
- return this.success('test');
- }
- };
可以通过
http://localhost:8080/api/test
访问:
- {
- errno: 0,
- errmsg: "",
- data: "test"
- }
添加新页面 abc
在 client 的 src/pages 目录下创建新的页面
src/pages/abc/abc.html
, 同时修改
webpack.dev.config.js
,historyApiFallback 中添加新的页面路由.
- historyApiFallback: {
- rewrites: [
- { from: /^\/$/, to: '/index.html' },
- { from: /^\/admin\/?$/, to: '/admin.html' },
- { from: /^\/abc\/?$/, to: '/abc.html' },
- { from: /./, to: '/404.html' }
- ],
- },
在 server 的
src/controller/index.js
中创建新的 action
- const Base = require('./base.js');
- module.exports = class extends Base {
- ...
- abcAction() {
- return this.display('abc.html');
- }
- _404Action() {
- return this.display('404.html');
- }
- };
修改 router.js 添加新路由:
- module.exports = [
- [/^\/api\/(.*)/i, '/:1'],
- [/^\/$/i, '/'],
- [/^\/admin\/?$/i, '/index/admin'],
- [/^\/abc\/?$/i, '/index/abc'],
- [/\//, 'index/_404', 'get']
- ];
分别重启 sever,client 即可.
生产环境构建
生产环境构建非常简单, 直接在 client 下运行 npm run build , 将 dist 下生成的文件 *.html 拷贝到 server 的 view 目录下, 将 dist/static 目录拷贝到 server 的 www 目录下, 然后将 server 部署到生产环境运行即可.
来源: http://www.tuicool.com/articles/UFFZ7bM