Why multiple pages

Recently, a new attempt has been made in the core business, abandoning the bloated multi-page application model of PHP backend rendering and transforming the entire site into a single-page application. Single-page rendering has greatly improved loading speed, and MVVM mode frees front-end development from tedious DOM manipulation. Multi-page separation reduces module coupling, especially when the application complexity is high. After that, different schemes can be tried in each single page, which is conducive to expansion. This article is to record the idea of multi-single page practice, scaffolding VUE-CLI generation, detailed code can refer to demo, welcome to discuss.

Webpck builds multiple single pages

1. Import files fromentrySpeaking of

The entry object is used to configure the application JS entry file. The module name is the property name (the name of js chunks generated by compilation), and the JS file path is the property value. This section takes vuE-CLI single-page application as an example. The following is the initial configuration. Single-page applications usually have only one entry JS file (excluding other common JS modules).

Multi-page applications have multiple JS entry files, and entry needs to be configured with multiple entry files, as follows: webpack.base.conf.js

  entry: {
    'index': './src/pages/main.js'// index.html entry file'asset': './src/pages/asset/index.js',// the entry file for the page asset.html'login': './src/pages/login/index.js',// the entry file for the page login.html},Copy the code

When pages are heavily used, glob modules can be introduced to encapsulate traversal functions.

Var glob = require('glob'); // iterate over the functionfunctiongetEntry(globPath) { var entries = {}, basename, tmp, pathname; Glob.sync (globPath).foreach (globPath)function (entry) {
    basename = path.basename(entry, path.extname(entry));
    console.log("basename",basename);
    tmp = entry.split('/').splice(-3);
    pathname = tmp.splice(0, 1) + '/' + tmp.splice(0, 1) + '/'+ basename; // Correct output of js and HTML path entries[pathname] = entry; });returnentries; } // Entries =getEntry() var entries=getEntry('./src/pages/**/main.js'); // Pass value entry: entries,Copy the code

For more details about Entry, please refer to the official website.

2. The multi-page application needs to be modifiedHtmlWebpackPluginConfigure the page rendering template

webpack.dev.conf.js

New HtmlWebpackPlugin({// access filename:'pages/login/login.html',
      template: './src/pages/login/login.html',
      inject: true, // Corresponding entry name chunks:['login']
    }),
    new HtmlWebpackPlugin({
      filename: 'pages/asset/asset.html',
      template: './src/pages/asset/asset.html',
      inject: true,
      chunks:['asset']}),Copy the code

Write it as traversal: webpack.dev.conf.js

 var pages = getEntry('./src/pages/**/*.html');
for (var pathname inPages) {// Configure the generated HTML file, define the path etc var conf = {filename: pathname +'.html', template: pages[pathname], // Template path inject:true// insert javascript at the end of the HTML};if (pathname inBasewebpackconfig.entry) {// Here configure the chunks conf.chunks = ['manifest'.'vendor',pathname];
    conf.hash = true; } devWebpackConfig.plugins.push(new HtmlWebpackPlugin(conf)); } // iterate over the functionfunction getEntry(globPath) {
  var entries = {}, basename, tmp, pathname;

  glob.sync(globPath).forEach(function (entry) {
    basename = path.basename(entry, path.extname(entry));
    tmp = entry.split('/').splice(-3);
    pathname = tmp.splice(0, 1) + '/' + tmp.splice(0, 1) + '/'+ basename; // Correct output of js and HTML path entries[pathname] = entry; });return entries;
}

Copy the code

Webpack builds more than a single page with some tread holes

  1. PostCss Loader and OptimizeCSSPlugin are incompatible with each other. Solution: Remove the following code.
    new OptimizeCSSPlugin({
      cssProcessorOptions: config.build.productionSourceMap
        ? { safe: true, map: { inline: false } }
        : { safe: true}}),Copy the code
  1. cannot find the element #appThe single-page page loads entry files of other pages, and the corresponding template ID cannot be found. Solution: In webPack configuration, in frontHtmlWebpackPluginThe configuration injects only the specifiedchunksIn this way, js of other pages will not be loaded in, leading to the failure to find the corresponding HTML template, and the loading is optimized.
   if (pathname inBasewebpackconfig.entry) {// Here configure the chunks conf.chunks = ['manifest'.'vendor',pathname];
    conf.hash = true;
   }
Copy the code
  1. Multiple single-page naming problems The ID of the root element of multiple single-page VUE applications must be different; otherwise, the pages may overwrite each other.
New Vue({// root element id el:'#app',
     components: { App },
     template: '<App/>'
    })
Copy the code
  1. Import is the ES6 specification, and require is the commonJS specification. It should be noted that import will improve the effect, and import may overwrite the require style.
require('/style.css');
import '/style.css';
Copy the code
  1. Vuex data cannot be shared between multiple single-page applications. Vuex data cannot be shared between single-page applications, because they are multi-page applications in nature. Data from page to page is still passed through URL or read through cache. This increases the application complexity to a certain extent, so the separation of business granularity should not be too fine. Try to ensure that a single business process is in a single page and data can be shared.

  2. Consider subsequent deployment. Single-page application deployment is simple, consisting of only one HTML file. In a multi-page solution, you must communicate with O&M in advance about subsequent deployment to ensure a smooth transition.