Backend Development 8 min read

Integrating ThinkJS with Vue2 for a Multi‑Page Project: Full Configuration Guide

This article provides a step‑by‑step tutorial on building a simple ThinkJS + Vue2 project with separate user and admin pages, covering directory layout, proxy setup, multi‑page webpack configuration, server routing, API creation, adding new pages, and production build deployment.

360 Tech Engineering
360 Tech Engineering
360 Tech Engineering
Integrating ThinkJS with Vue2 for a Multi‑Page Project: Full Configuration Guide

Today we discuss how to combine two powerful frameworks, ThinkJS and Vue2, to build a simple project that has both a user side and an admin interface, each implemented as a separate single‑page application served by ThinkJS APIs.

Project directory structure is shown below:

. 
├── 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 configuration starts with a Vue‑CLI generated project using webpack. In config/index.js a proxyTable is added to forward /api requests to the ThinkJS server:

proxyTable: {
  '/api': {
    target: 'http://localhost:8360/api/',
    changeOrigin: true,
    pathRewrite: { '^/api': '/' }
  }
},

To turn the single‑page app into a multi‑page application, the project structure is adjusted: a new folder src/pages/index is created and the original files ( src/assets , src/router , src/App.vue , src/main.js , ./index.html ) are moved there, renaming main.js to index.js .

In build/utils.js the following helper functions are added to generate entry points and HTML plugins for each page using glob :

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;
};

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',
      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);
  });
};

The webpack entry configuration in build/webpack.base.conf.js is replaced with utils.entries() , and the plugin list in both webpack.dev.conf.js and webpack.prod.conf.js now includes utils.htmlPlugin() .

Additional pages are created under src/pages (e.g., admin , 404 ) with corresponding HTML templates, and the historyApiFallback rewrites in the dev server are updated to serve the correct HTML files for / , /admin , and any unknown routes.

Server configuration uses ThinkJS’s think-cli . In src/config/router.js routes are added to map API calls and page requests:

module.exports = [
  [/^\/api\/(.*)/i, '/:1'],
  [/^\/$/i, '/'],
  [/^\/admin\/?$/i, '/index/admin'],
  [/\//, 'index/_404', 'get']
];

The main controller ( src/controller/index.js ) renders the appropriate HTML files:

class Index extends Base {
  indexAction() { return this.display('index.html'); }
  adminAction() { return this.display('admin.html'); }
  _404Action() { return this.display('404.html'); }
}

Any controller method exposed under /api becomes reachable via /api/controller/action . An example test controller returns a JSON response:

{ "errno": 0, "errmsg": "", "data": "test" }

To add a new page abc , a folder src/pages/abc with abc.html is created, the dev server’s historyApiFallback rewrites are extended, and a new abcAction is added to the controller along with a matching route entry.

Production build is performed by running npm run build inside the client directory. The generated dist/*.html files are copied to the server’s view directory, and dist/static is moved to server/www . After deployment the server serves the pre‑built assets.

Following these steps results in a fully functional ThinkJS + Vue2 multi‑page application with separate user and admin interfaces, API endpoints, and a ready‑to‑deploy production build.

Frontend DevelopmentBackend DevelopmentNode.jsWebpackVue2thinkjsMulti-Page Application
360 Tech Engineering
Written by

360 Tech Engineering

Official tech channel of 360, building the most professional technology aggregation platform for the brand.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.