zoukankan      html  css  js  c++  java
  • vue项目构建过程

    # template 模版项目

    > A Vue.js project
    * 构建过程
    * 安装过程
    * 差异点
    * 打包优化


    ## 构建过程
    ```bash
    bogon:vue-cli caoke$ vue init webpack template

    ? 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

    vue-cli · Generated "template".


    # Installing project dependencies ...
    # ========================
    ```

    ## 1、安装过程

    ``` bash
    # 安装依赖
    npm install

    # 启动热服务 localhost:8080
    npm run dev

    # 压缩打包
    npm run build

    # 压缩打包 and 查看打包分析图
    npm run build --report

    # 打包成测试环境
    "deployTest": "cross-env assetsPublicPath=//zx.test.17zuoye.net/ node build/build.js",

    # 打包成线上环境
    "deployOnline": "cross-env assetsPublicPath=//www.17zuoye.com/ node build/build.js",


    ```
    ### 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 页面

    ```
    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",
    ```

    2-3:webpack.prod.conf.js 自动配置entry,看打包优化部分
    ```
    const test = require('./better');

    const entry=test.getproEntry()
    const htmlConfig=test.getproHtmlWebpack();
    const commonsConfig=test.getCommonsChunk();

    entry: entry,

    chunkFilename: utils.assetsPath('js/[name].[chunkhash].js')

    ...htmlConfig,
    ...commonsConfig,

    // 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
    // )
    // }
    // }),

    // new webpack.optimize.CommonsChunkPlugin({
    // name: 'manifest',
    // minChunks: Infinity
    // }),

    ```
    2-4:webpack.dev.conf.js 自动配置entry
    ```
    const test = require('./better');

    const entry=test.getdevEntry()

    const htmlConfig=test.getdevHtmlWebpack();

    entry: entry,

    ...htmlConfig,


    ```
    2-4:vue-loader.conf.js
    ```
    esModule: false
    ```

    2-5:config/index.js
    ```
    const productName = require('../package').name||'template';
    dev: {

    // 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'
    }
    }

    },


    build: {
    // Template for index.html
    index: path.resolve(__dirname, '../../dist/'+productName+'/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../../dist'),
    assetsSubDirectory: productName,
    assetsPublicPath: '/',


    productionSourceMap: false,

    ```

    ## 3、自动配置和打包优化
    * 3-1:根据entry目录,自动配置入口和html,以dev开头的文件不会发布到生产环境.
    * 3-2:以公共文件名开头的文件,回生产公共文件。如a.demo.js、b.demo.js生产公共文件a.js。
    * 3-3:子目录也遵循上述规范,也会生产对应的html、js、公共文件
    * 3-3:在better.js手动配置公共的js,格式如下
    ```
    const commonConfig={
    'demo':['demo1','demo2'],//demo1、demo2的公共demo.js
    // 'vendor':true,//所有页面的公共demo.js
    }
    ```

    build/better.js

    ```
    //打包优化配置
    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();

    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]
    }
    })
    }

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

    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')

    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')

    const entry={}
    arr.forEach(function (file) {
    file.replace(/entry/(.+).js$/,function (m,p1) {
    entry[p1]=file
    })
    })


    return entry;
    }

    /*
    生产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=[]

    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,//自动配置生产环境公共资源
    };


    ```

    ## 4、入口模板
    ```
    //引入公共配置
    import Vue from '../common/pcbase';
    /*
    2、注册 组件容器
    展示组件的容器
    * */
    Vue.component('card', require('../components/card.vue'));

    //1、导入elm ui
    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    Vue.use(ElementUI, { size: 'small' });

    //项目的入口
    import App from '../views/demo2'

    /* eslint-disable no-new */
    new Vue({
    el: '#app',
    components: { App },
    template: ' <div><mv-modal></mv-modal><App/></div>'
    })

    ```
    ## 5、打包构建速度优化
    使用多线程压缩打包插件 webpack-parallel-uglify-plugin
    ```
    const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')

    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=[
    {

    //本地的url =》 本地的url
    // "/":"/mteacher/tcbag.html",
    },{
    //线上的url =》 本地的mock
    "/ok":"/ok",
    }
    ]

    ```
  • 相关阅读:
    项目后台的最新认识和对MVC封装性、可维护性的更深刻认识!
    java综述
    android模拟器里输出程序:HelloWorld
    JAVA程序员必去的网站
    1.MVC框架复习 2.Ajax加强 3.搜索建议 4,三级联动 5、刷新分页 6、Ajax局部动态更新数据
    jQuery的几个例子流程讲解
    1.jQuery基础语法 2.jQuery选择器、操作页面文档元素 3.jqueryDOM操作 4.jqueryCSS操作 5.Jquery事件 6.Jquery动画
    成功站长应具备的良好心态
    java的学习步骤方法书籍大总结
    Java常用类
  • 原文地址:https://www.cnblogs.com/caoke/p/9525613.html
Copyright © 2011-2022 走看看