1. # template 模版项目
  2.  
  3. > A Vue.js project
    * 构建过程
    * 安装过程
    * 差异点
    * 打包优化
  4.  
  5. ## 构建过程
    ```bash
    bogon:vue-cli caoke$ vue init webpack template
  6.  
  7. ? Project name template
    ? Project description A Vue.js project
    ? Author caoke <caoke@caoke.com>
    ? Vue build standalone
    ? Install vue-router? Yes
    ? Use ESLint to lint your code? No
    ? Set up unit tests No
    ? Setup e2e tests with Nightwatch? No
    ? Should we run `npm install` for you after the project has been created? (recommended) npm
  8.  
  9. vue-cli · Generated "template".
  10.  
  11. # Installing project dependencies ...
    # ========================
    ```
  12.  
  13. ## 1、安装过程
  14.  
  15. ``` bash
    # 安装依赖
    npm install
  16.  
  17. # 启动热服务 localhost:8080
    npm run dev
  18.  
  19. # 压缩打包
    npm run build
  20.  
  21. # 压缩打包 and 查看打包分析图
    npm run build --report
  22.  
  23. # 打包成测试环境
    "deployTest": "cross-env assetsPublicPath=//zx.test.17zuoye.net/ node build/build.js",
  24.  
  25. # 打包成线上环境
    "deployOnline": "cross-env assetsPublicPath=//www.17zuoye.com/ node build/build.js",
  26.  
  27. ```
    ### 2、差异点
    2-1:新建目录
    ```
    /src/api 服务接口口请求
    /src/assets png、js、css资源存放
    /src/common 公用资源
    /src/components 项目内部组件
    /src/directive vue指令
    /src/entry 入口js
    /src/marvel 第三份公用组件库
    /src/models 数据模型
    /src/router 路由
    /src/utils 公用工具
    /src/views 页面
  28.  
  29. ```
    2-2:package.json
    ```
    "axios": "^0.18.0",
    "element-ui": "^2.3.8",
    "glob": "^7.1.2",
    "less": "^3.0.2",
    "less-loader": "^4.1.0",
    "node-sass": "^4.9.0",
    "photoswipe": "^4.1.2",
    "qs": "^6.5.2",
    "sass-loader": "^7.0.1",
    "stylus": "^0.54.5",
    "stylus-loader": "^3.0.2",
    "text-loader": "^0.0.1",
    "vue-markdown": "^2.2.4",
    ```
  30.  
  31. 2-3:webpack.prod.conf.js 自动配置entry,看打包优化部分
    ```
    const test = require('./better');
  32.  
  33. const entry=test.getproEntry()
    const htmlConfig=test.getproHtmlWebpack();
    const commonsConfig=test.getCommonsChunk();
  34.  
  35. entry: entry,
  36.  
  37. chunkFilename: utils.assetsPath('js/[name].[chunkhash].js')
  38.  
  39. ...htmlConfig,
    ...commonsConfig,
  40.  
  41. // new webpack.optimize.CommonsChunkPlugin({
    // name: 'vendor',
    // minChunks (module) {
    // // 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
    // )
    // }
    // }),
  42.  
  43. // new webpack.optimize.CommonsChunkPlugin({
    // name: 'manifest',
    // minChunks: Infinity
    // }),
  44.  
  45. ```
    2-4:webpack.dev.conf.js 自动配置entry
    ```
    const test = require('./better');
  46.  
  47. const entry=test.getdevEntry()
  48.  
  49. const htmlConfig=test.getdevHtmlWebpack();
  50.  
  51. entry: entry,
  52.  
  53. ...htmlConfig,
  54.  
  55. ```
    2-4:vue-loader.conf.js
    ```
    esModule: false
    ```
  56.  
  57. 2-5:config/index.js
    ```
    const productName = require('../package').name||'template';
    dev: {
  58.  
  59. // Paths
    assetsSubDirectory: productName,
    assetsPublicPath: '/',
    proxyTable: {
    /*
    域名:https://www.easy-mock.com/
    用户名:caoke
    密码:123456
    * */
    '/api': {
    target: 'https://www.easy-mock.com/', // 接口的域名
    secure: false, // 如果是https接口,需要配置这个参数
    changeOrigin: true, // 如果接口跨域,需要进行这个参数配置
    pathRewrite: {
    '/api': '/mock/596f19b1a1d30433d837ad7d/example'
    }
    }
  60.  
  61. },
  62.  
  63. build: {
    // Template for index.html
    index: path.resolve(__dirname, '../../dist/'+productName+'/index.html'),
  64.  
  65. // Paths
    assetsRoot: path.resolve(__dirname, '../../dist'),
    assetsSubDirectory: productName,
    assetsPublicPath: '/',
  66.  
  67. productionSourceMap: false,
  68.  
  69. ```
  70.  
  71. ## 3、自动配置和打包优化
    * 3-1:根据entry目录,自动配置入口和html,以dev开头的文件不会发布到生产环境.
    * 3-2:以公共文件名开头的文件,回生产公共文件。如a.demo.jsb.demo.js生产公共文件a.js
    * 3-3:子目录也遵循上述规范,也会生产对应的htmljs、公共文件
    * 3-3:在better.js手动配置公共的js,格式如下
    ```
    const commonConfig={
    'demo':['demo1','demo2'],//demo1、demo2的公共demo.js
    // 'vendor':true,//所有页面的公共demo.js
    }
    ```
  72.  
  73. build/better.js
  74.  
  75. ```
    //打包优化配置
    const glob = require('glob');
    const path = require('path');
    const webpack = require('webpack')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const productName = require('../package').name||'template';
    /*
    * a.demo1.js、a.demo2.js
    * 表示存在公共的a.js,
    * 会生产 a.[md5].js a.demo1.[md5].js a.demo2.[md5].js 3个文件
    *
    * */
    //公共模块的配置
    const commonConfig=getcommons();
  76.  
  77. function getcommons(){
    const obj=getproEntry();
    const commonCache={}
    const commonConfig={}
    for(let ke in obj){
    ke.replace(/([a-z]+)\./i,function (m,p1) {
    if(!commonCache[p1]){commonCache[p1]=[];}
    commonCache[p1].push(ke)
    if(commonCache[p1].length==2){
    commonConfig[p1]=commonCache[p1]
    }
    })
    }
  78.  
  79. return commonConfig;
    }
    function getCommonsChunk() {
    const data=[]
    for(let name in commonConfig){
    if(Array.isArray(commonConfig[name])){
    data.push(
    new webpack.optimize.CommonsChunkPlugin({
    name: name,
    minChunks:2,
    chunks:commonConfig[name]
    }))
    }
    }
    return data;
    }
  80.  
  81. function getCommonBy(cname) {
    const commons=[]
    for(let name in commonConfig){
    if(commonConfig[name].length>0&&commonConfig[name].indexOf(cname)>-1){
    commons.push(name)
    }
    }
    return commons;
    }
    /*
    获取入口entry的所有js文件
    */
    function getdevEntry() {
    const arr = glob.sync(__dirname+'/../src/entry/**/*.js')
  82.  
  83. const entry={}
    arr.forEach(function (file) {
    file.replace(/entry\/(.+)\.js$/,function (m,p1) {
    entry[p1]=file
    })
    })
    return entry;
    }
    //获取生产环境入口配置
    function getproEntry() {
    const arr = glob.sync(__dirname+'/../src/entry/**/!(dev.)*.js')
  84.  
  85. const entry={}
    arr.forEach(function (file) {
    file.replace(/entry\/(.+)\.js$/,function (m,p1) {
    entry[p1]=file
    })
    })
  86.  
  87. return entry;
    }
  88.  
  89. /*
    生产html配置
    */
    function getdevHtmlWebpack() {
    const entry=getdevEntry();
    const htmlConfig=[]
    for(let name in entry){
    htmlConfig.push(new HtmlWebpackPlugin({
    title:name,
    filename: productName+'/'+name+'.html',
    template: 'index.html',
    inject: true,
    chunks:[name],
    chunksSortMode: 'dependency'
    }))
    }
    return htmlConfig;
    }
    function getproHtmlWebpack() {
    const entry=getproEntry();
    const htmlConfig=[]
  90.  
  91. for(let name in entry){
    const cmchunks=getCommonBy(name);
    htmlConfig.push(new HtmlWebpackPlugin({
    title:name,
    filename: path.resolve(__dirname, '../../dist/'+productName+'/'+name+'.html'),
    template: 'index.html',
    inject: true,
    minify: {
    removeComments: true,
    // collapseWhitespace: true,
    removeAttributeQuotes: true
    // more options:
    // https://github.com/kangax/html-minifier#options-quick-reference
    },
    chunks:[...cmchunks,name],
    chunksSortMode: 'manual'
    }))
    }
    return htmlConfig;
    }
    module.exports={
    getdevEntry,//自动配置开发环境入口
    getproEntry,//自动配置生产环境入口
    getdevHtmlWebpack,//自动配置开发环境html
    getproHtmlWebpack,//自动配置生产环境入口
    getCommonsChunk,//自动配置生产环境公共资源
    };
  92.  
  93. ```
  94.  
  95. ## 4、入口模板
    ```
    //引入公共配置
    import Vue from '../common/pcbase';
    /*
    2、注册 组件容器
    展示组件的容器
    * */
    Vue.component('card', require('../components/card.vue'));
  96.  
  97. //1、导入elm ui
    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    Vue.use(ElementUI, { size: 'small' });
  98.  
  99. //项目的入口
    import App from '../views/demo2'
  100.  
  101. /* eslint-disable no-new */
    new Vue({
    el: '#app',
    components: { App },
    template: ' <div><mv-modal></mv-modal><App/></div>'
    })
  102.  
  103. ```
    ## 5、打包构建速度优化
    使用多线程压缩打包插件 webpack-parallel-uglify-plugin
    ```
    const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')
  104.  
  105. new AssetsPlugin({
    prettyPrint:true,
    fullpath:true
    }),
    new ParallelUglifyPlugin({
    cacheDir: '.cache/',
    uglifyJS:{
    output: {
    comments: false
    },
    compress: {
    warnings: false
    }
    }
    }),
    ```
    ## 6、本地mock
    原理:路由的rewrite,以及代理插件
    1、是否以http开头,用代理转发到url
    2、以"/"开头,则在本地目录查找,是否存在该文件,返回该文件的json数据
    3、不存在就做路由转发
    ```
    module.exports=[
    {
  106.  
  107. //本地的url =》 本地的url
    // "/":"/mteacher/tcbag.html",
    },{
    //线上的url =》 本地的mock
    "/ok":"/ok",
    }
    ]
  108.  
  109. ```

vue项目构建过程的更多相关文章

  1. vue项目构建与实战

    关于 微信公众号:前端呼啦圈(Love-FED) 我的博客:劳卜的博客 知乎专栏:前端呼啦圈 前言 由于vue相对来说比较平缓的学习过程和新颖的技术思路,使其受到了广大前后端开发者的青睐,同时其通俗易 ...

  2. (转)Maven学习总结(二)——Maven项目构建过程练习

    孤傲苍狼 只为成功找方法,不为失败找借口! Maven学习总结(二)——Maven项目构建过程练习 上一篇只是简单介绍了一下maven入门的一些相关知识,这一篇主要是体验一下Maven高度自动化构建项 ...

  3. Maven学习总结(2)——Maven项目构建过程练习

    Maven学习总结(二)--Maven项目构建过程练习 上一篇只是简单介绍了一下maven入门的一些相关知识,这一篇主要是体验一下Maven高度自动化构建项目的过程 一.创建Maven项目 1.1.建 ...

  4. 通过调试vue-cli 构建代码学习vue项目构建运行过程

    我们知道vue-cli 3.0之前直接基于webpack创建对应配置文件,我们通过学习webpack就能够了解其构建过程,然而从vue-cli 3.0开始,vue-cli命令行更改为@vue/cli以 ...

  5. 利用vue-cli3快速搭建vue项目详细过程

    一.介绍 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统.有三个组件: CLI:@vue/cli 全局安装的 npm 包,提供了终端里的vue命令(如:vue create .vue ...

  6. Maven学习总结(二)——Maven项目构建过程练习

    上一篇只是简单介绍了一下maven入门的一些相关知识,这一篇主要是体验一下Maven高度自动化构建项目的过程 一.创建Maven项目 1.1.建立Hello项目 1.首先建立Hello项目,同时建立M ...

  7. Maven学习总结(二)——Maven项目构建过程练习_转载

    上一篇只是简单介绍了一下maven入门的一些相关知识,这一篇主要是体验一下Maven高度自动化构建项目的过程 一.创建Maven项目 1.1.建立Hello项目 1.首先建立Hello项目,同时建立M ...

  8. 转】Maven学习总结(二)——Maven项目构建过程练习

    原博文出自于:http://www.cnblogs.com/xdp-gacl/p/4051690.html 感谢! 上一篇只是简单介绍了一下maven入门的一些相关知识,这一篇主要是体验一下Maven ...

  9. Maven学习(二)-- Maven项目构建过程练习

    摘自:http://www.cnblogs.com/xdp-gacl/p/4051690.html 一.创建Maven项目 1.1.建立Hello项目 1.首先建立Hello项目,同时建立Maven约 ...

随机推荐

  1. Windows Cmder

    一.简介 作为一个程序员,即使是在windows工作环境,cmd也是我们必不可少的使用工具.cmder 是为 Windows 提供的一个便携式控制台仿真器,用来替代windows的cmd,使用非常简单 ...

  2. 10.IN 操作符

    IN 操作符 IN 操作符允许我们在 WHERE 子句中规定多个值. SQL IN 语法 SELECT column_name(s) FROM table_name WHERE column_name ...

  3. asp.net web 自定义控件

    0.调用代码 protected override void Page_Load(object sender, EventArgs e) { //给基类服务接口复制,可不付 if (IsPostBac ...

  4. Oracle——SQL基础

    一.SQL语句分为以下三种类型: DML: Data Manipulation Language 数据操纵语言DDL: Data Definition Language 数据定义语言DCL: Data ...

  5. 运行maven build报错No goals have been specified for this build.

    运行maven报错: [ERROR] No goals have been specified for this build. You must specify a valid lifecycle p ...

  6. 编写高质量代码改善C#程序的157个建议——建议44:理解委托中的协变

    建议44:理解委托中的协变 委托中的泛型变量天然是部分支持协变的.为什么是“部分支持协变”?看下面示例: class Program { public delegate T GetEmployeeHa ...

  7. 浅谈delphi创建Windows服务程序与窗体实现交互

    我想实现的功能是创建一个服务程序,然后在服务Start时动态创建一个窗体Form,然后把Form缩小时变成TrayIcon放在Windows托盘上. 我在服务程序的OnStart事件中写到 Start ...

  8. C#委托同步异步说明,并比较control调用Invoke和BeginInvoke的异同

    一.委托的同步和异步: 1.同步 使用Invoke调用同步,或直接写fun1("func"),在fun1.Invoke这一步会明显的阻塞线程 使用: static void Mai ...

  9. kali linux之主动信息收集(二层发现)

    主动信息收集: 直接与目标系统交互信息,无法避免留下访问的痕迹 使用受控的第三方电脑进行探测,如(使用代理或者使用肉鸡,做好被封杀的准备,使用噪声迷惑目标,淹没真实的探测流量) 识别活着的主机,会有潜 ...

  10. VS2010 UAC执行级别修改

    配置属性 -> 链接器 -> 清单文件 -> UAC执行级别 改为 requireAdministrator 这个级别即可.