Skip to content

基于vue-cli搭建一个多页面应用(一)--基础结构搭建 #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
tonyfree opened this issue Mar 22, 2017 · 9 comments
Open

Comments

@tonyfree
Copy link
Owner

tonyfree commented Mar 22, 2017

1.全局安装vue-cli:Vue.js官方提供的用于快速创建项目模板的脚手架工具

$ npm install -g vue-cli 

$ yarn global add vue-cli

2.创建项目模板:官方提供了五个模板--webpack、webpack-simple、browserify、browserify-simple、simple,选择webpack模板

$ vue init webpack project-name

3.在安装过程中会有一些提示:
1)Vue build这个选项选择Runtime + Compiler
2)安装vue-router,ESLint、Karma+Mocha、Nightwatch根据需求选择安装


3)根据提示操作,即可成功启动项目

4.现在创建的项目模板是单页面应用,与多页面应用还有些差别,需要做一些调整:
1)项目目录结构的调整:

在开发路径src下增加modules和pages文件夹,分别存放模块和页面
有关页面的所有文件都放到同一文件夹下就近管理:index.html(页面模板)、main.js(页面入口文件)、App.vue(页面使用的组件,公用组件放到components文件夹下)、router(页面的路由配置)、assets(页面的静态资源)都移到index文件夹下,并把main.js改为index.js,保证页面的入口js文件和模板文件的名称一致

2)在build/utils.js中添加两个方法:webpack多入口文件和多页面输出

var path = require('path')
var glob = require('glob')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var PAGE_PATH = path.resolve(__dirname, '../src/pages')
var merge = require('webpack-merge')

//多入口配置
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')
  let arr = []
  entryHtml.forEach((filePath) => {
    let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'))
    let conf = {
      template: filePath,
      filename: filename + '.html',
      chunks: [filename],
      inject: true
    }
    if (process.env.NODE_ENV === 'production') {
      conf = merge(conf, {
        chunks: ['manifest', 'vendor', filename],
        minify: {
          removeComments: true,
          collapseWhitespace: true,
          removeAttributeQuotes: true
        },
        chunksSortMode: 'dependency'
      })
    }
    arr.push(new HtmlWebpackPlugin(conf))
  })
  return arr
}

3)修改build/webpack.base.conf.js的入口配置

module.exports = {
  entry: utils.entries(),
...

4)修改build/webpack.dev.conf.js和build/webpack.prod.conf.js的多页面配置:把原有的页面模板配置注释或删除,并把多页面配置添加到plugins
webpack.dev.conf.js:

  plugins: [
    ......
    //  new HtmlWebpackPlugin({
    //    filename: 'index.html',
    //    template: 'index.html',
    //    inject: true
    //  }),
    ......
  ].concat(utils.htmlPlugin())

webpack.prod.conf.js:

  plugins: [
    ......
    // new HtmlWebpackPlugin({
    //   filename: config.build.index,
    //   template: 'index.html',
    //   inject: true,
    //   minify: {
    //     removeComments: true,
    //     collapseWhitespace: true,
    //     removeAttributeQuotes: true
    //   },
    //   chunksSortMode: 'dependency'
    // }),
    ......
  ].concat(utils.htmlPlugin())

补充说明:在上面多页面输出配置中有这样一行代码:

  chunks: ['manifest', 'vendor', filename],

这是html-webpack-plugin插件对页面入口文件(即js文件)的限定,如果不设置则会把整个项目下的所有入口文件全部引入
为什么要引入'manifest'和'vendor',在build/webpack.prod.conf.js中有如下代码:

    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module, count) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    }),

vendor模块是指提取涉及node_modules中的公共模块
manifest模块是对vendor模块做的缓存
关于CommonsChunkPlugin插件的详细说明请阅读官方文档

关于html-webpack-plugin插件的配置还有一行代码:

chunksSortMode: 'dependency'

插件会按照模块的依赖关系依次加载,即:manifest,vendor,本页面入口,其他页面入口...

至此,多页面应用已经搭建完毕,只需要在pages文件夹创建相应的页面文件即可。

本系列文章:

  1. 基础结构的搭建
  2. postcss插件和css预编译配置
  3. 路径别名和模块自动加载配置
  4. rap自动切换配置
  5. 自动化部署
  6. 移动端适配方案
  7. UI库的选择和使用
  8. 移动调试和异常监控
@ishowman
Copy link

ishowman commented Jan 4, 2018

请问打包相关的文件要如何修改?

@ifredom
Copy link

ifredom commented May 23, 2018

不行的 是否有可以实际运行的demo?

@tonyfree
Copy link
Owner Author

@jimmyspace-ch
Copy link

seo怎么解决

@tonyfree
Copy link
Owner Author

tonyfree commented Jun 5, 2018

@jimmyspace-ch 直接在相应的页面上配置即可,如果是类似商品详情页则需要生成静态页面

@osinglee
Copy link

osinglee commented Jun 6, 2018

如果another页面也是一个单页面,那么我需要在another里面创建index.js 并new Vue({})吗,如果是那么能否共享store

@tonyfree
Copy link
Owner Author

tonyfree commented Jun 6, 2018

@osinglee 如果index.js你指的是another.html对应的入口文件的话,名称你可以设置的,入口文件是需要实例化Vue的;在单页的入口文件注入store是全局的(在此单页下是全局的)

@osinglee
Copy link

@tonyfree 跟我预想的一样,谢谢你的回答

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants
@tonyfree @ifredom @ishowman @osinglee @jimmyspace-ch and others