grapewheel / avvw

Apicloud + Vue2 + Vant(有赞前端)+ Webpack4打包,极速开发APP框架,将apicloud的渲染效率和vue数据绑定特性发挥极致!
153 stars 55 forks source link

使用 手机实时调试 提示 [WDS] Disconnected! #23

Closed viarotel closed 5 years ago

grapewheel commented 5 years ago

请具体描述下场景,什么时候触发?怎么重现

viarotel commented 5 years ago

更改支持多级目录时出现的

viarotel commented 5 years ago
  1. 建议 vant 通过 cdn 的方式引入

  2. 资源文件 可以分目录

  3. 使用 手机实时调试 提示 [WDS] Disconnected!

    /*
    * webpack.base.js
    **/
    const VueLoaderPlugin = require('vue-loader/lib/plugin')
    const CopyWebpackPlugin = require('copy-webpack-plugin')
    const resolve = require('path').resolve
    
    module.exports = {
     output: {
       path: resolve(__dirname, 'dist'),
       filename: './js/[name].js'
     },
     module: {
       rules: [
         {
           test: /\.vue$/,
           loader: 'vue-loader'
         },
         {
           test: /\.css$/,
           use: [
             'style-loader',
             'css-loader'
           ]
         },
         {
           test: /\.(png|svg|jpg|gif)$/,
           loader: 'file-loader',
           options: {
               outputPath: './image',
               publicPath: './image'
           }
         },
         {
           test: /\.(woff|woff2|eot|ttf|otf)$/,
           loader: 'file-loader'
         },
         {
           test: /\.js$/,
           loader: 'babel-loader',
           options: {
             cacheDirectory: true
           },
           exclude: file => (
             /node_modules/.test(file) &&
             !/\.vue\.js/.test(file)
           )
         }
       ]
     },
     plugins: [
       new VueLoaderPlugin(),
       new CopyWebpackPlugin([
         { from: './config.xml', to: './' },
         // { from: './src/image', to: './image' },
         { from: './src/css/api.css', to: './css' },
         { from: './src/css/common.css', to: './css' },
         { from: './src/libs/iconfont/iconfont.css', to: './css' },
         { from: './src/libs/vant/vant.css', to: './css' },
         { from: './src/libs/vant/vant.min.js', to: './js' },
         { from: './src/libs/fastclick.min.js', to: './js' },
         { from: './src/libs/api.js', to: './js' },
         { from: './src/script/common.js', to: './js' },
         { from: './src/script/APICloud_utils.js', to: './js' },
         { from: './src/script/const.js', to: './js' }
     ]),
     ],
     resolve: {
       alias: {
         '@': resolve('./src')
       }
     }
    }
    /*
    * webpack.dev.js
    **/
    const merge = require('webpack-merge')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const HotModuleReplacementPlugin = require('webpack').HotModuleReplacementPlugin
    const CopyWebpackPlugin = require('copy-webpack-plugin')
    const base = require('./webpack.base')
    const path = require('path')
    const fs = require('fs')
    
    let files = [];
    getAllVueFile('./src/pages'); //获取指定目录内所有文件
    
    // console.log(files);
    let entry = {}, htmlWebpacks = [];
    for (let file of files) {
       entry[file.name] = file.path;
       htmlWebpacks.push(new HtmlWebpackPlugin({
           name: file.name,
           apiCSS: './css/api.css',
           commonCSS: './css/common.css',
           iconfontCSS: './css/iconfont.css',
           vantCSS: './css/vant.css',
           vue: './js/vue.js',
           vantJS: './js/vant.min.js',
           fastclick: './js/fastclick.min.js',
           commonJS: './js/common.js',
           constJS: './js/const.js',
           apiJS: './js/api.js',
           filename: file.name + '.html',
           chunks: [file.name, 'runtime'],
           template: './src/templates/page.ejs'
       }))
    }
    
    function getAllVueFile(path) {
       let tempArr = fs.readdirSync(path); 
       tempArr.forEach(function(ele){
       let isDirectory = fs.statSync(path + '/' + ele).isDirectory(); //当前文件是否为目录
       if(isDirectory){
           getAllVueFile(path + '/' + ele);
       } else {
           files.push({
               path: path + '/' + ele,
               name: ele.replace('.vue',"")
           })
       }
     })
    }
    
    // Modify the index html for HMR!
    htmlWebpacks.push(new HtmlWebpackPlugin({
       env: 'development',
       filename: `index.html`,
       chunks: [],
       template: './src/templates/index.html'
    }))
    
    console.log(entry);
    module.exports = merge(base, {
       entry,
       mode: 'development',
       devtool: 'inline-source-map',
       devServer: {
           contentBase: path.resolve(__dirname, 'dist'),
           host: '0.0.0.0',
           useLocalIp: true,
           disableHostCheck: true,
           writeToDisk: file => {
               console.log(file);
               return /index.html$/.test(file)
           },
           hot: true
       },
       optimization: {
           runtimeChunk: {
               name: 'runtime'
           }
       },
       plugins: [
           new HotModuleReplacementPlugin(),
           new CopyWebpackPlugin([
               { from: './src/libs/vue.js', to: './js' }
           ]),
           ...htmlWebpacks
       ]
    })
    /*
    * webpack.prod.js
    **/
    const merge = require('webpack-merge')
    const CleanWebpackPlugin = require('clean-webpack-plugin')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const CopyWebpackPlugin = require('copy-webpack-plugin')
    const base = require('./webpack.base')
    const fs = require('fs')
    
    let files = [];
    function getAllVueFile(path) {
       let tempArr = fs.readdirSync(path); //获取指定目录内所有文件
       tempArr.forEach(function(ele){
       let isDirectory = fs.statSync(path + '/' + ele).isDirectory(); //当前文件是否为目录
       if(isDirectory){
           getAllVueFile(path + '/' + ele);
       } else {
           files.push({
               path: path + '/' + ele,
               name: ele.replace('.vue',""),
    
           })
       }
     })
    }
    getAllVueFile('./src/pages');
    
    console.log(files);
    let entry = {}, htmlWebpacks = [], path ='', jsPath = '';
    for (let file of files) {
       path = file.path.replace('.vue','').replace('/src/pages','');
       jsPath = retPath((path.split('/')).length-2);
       entry[file.name] = file.path;
       htmlWebpacks.push(new HtmlWebpackPlugin({
           name: file.name,
           apiCSS: jsPath + 'css/api.css',
           commonCSS: jsPath + 'css/common.css',
           iconfontCSS: jsPath + 'css/iconfont.css',
           vantCSS: jsPath + 'css/vant.css',
           vue: jsPath + 'js/vue.min.js',
           vantJS: jsPath + 'js/vant.min.js',
           fastclick: jsPath + 'js/fastclick.min.js',
           commonJS: jsPath + 'js/common.js',
           constJS: jsPath + 'js/const.js',
           apiJS: jsPath + 'js/api.js',
           filename: path +'.html',
           chunks: [file.name, 'runtime'],
           template: './src/templates/page.ejs'
       }))
    }
    
    function retPath(num){ // 获取资源路径
       let path = './';
       for (let idx = 0; idx < num; idx++) {
           path += '../';
       }
       return path;
    }   
    
    // Modify the index html for production!
    htmlWebpacks.push(new HtmlWebpackPlugin({
       env: 'production',
       filename: `index.html`,
       chunks: [],
       template: './src/templates/index.html'
    }))
    
    module.exports = merge(base, {
       mode: 'production',
       entry,
       optimization: {
           runtimeChunk: {
               name: 'runtime'
           }
       },
       plugins: [
           new CleanWebpackPlugin(),
           new CopyWebpackPlugin([
               { from: './src/libs/vue.min.js', to: './js' }
           ]),
           ...htmlWebpacks
       ]
    })
    
    /*
    * page.ejs
    **/
    <!doctype html>
    <html>
    <head>
       <meta charset="utf-8">
       <meta name="viewport"
             content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
       <meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
       <title>index</title>
    </head>
    <body>
    
    </body>
    </html>
    <script type="text/javascript">
     var url = './home.html'   // You can change the main entry in 'production' ENV
     if ('<%= htmlWebpackPlugin.options.env %>' === 'development') {
       url = 'http://192.168.0.109:8080/home.html' // You can change the main entry in 'development' ENV
     }
    
     apiready = function () {
       api.openFrame({
         name: 'home',
         url: url,
         rect: {
           x: 0,
           y: 0,
           w: api.winWidth,
           h: api.winHeight
         }
       })
     }
    </script>
    /*
    * index.html
    **/
    <!doctype html>
    <html>
    <head>
       <meta charset="utf-8">
       <meta name="viewport"
             content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
       <meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
       <title><%= htmlWebpackPlugin.options.name %></title>
       <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.apiCSS %>">
       <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.iconfontCSS %>">
       <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.vantCSS %>">
       <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.commonCSS %>">
    </head>
    <body>
    <div id="page">
       <vm><!-- Vue here --></vm>
    </div>
    <script type="text/javascript" src="<%= htmlWebpackPlugin.options.vue %>"></script>
    <script type="text/javascript" src="<%= htmlWebpackPlugin.options.vantJS %>"></script>
    <script type="text/javascript" src="<%= htmlWebpackPlugin.options.commonJS %>"></script>
    <script type="text/javascript" src="<%= htmlWebpackPlugin.options.fastclick %>"></script>
    <script type="text/javascript" src="<%= htmlWebpackPlugin.options.constJS %>"></script>
    <script type="text/javascript" src="<%= htmlWebpackPlugin.options.apiJS %>"></script>
    </body>
    </html>
    
    <script type="text/javascript">
       var page
    
       // Apicloud initialize
       apiready = function () {
         Vue.prototype.$ac = api // Vue global apicloud API
         page = new Vue({
           el: '#page',
           components: {
             vm
           },
           mounted: function () {
             Origami.fastclick(document.body) // You must use fastclick on the mobile
           }
         })
       }
    
       // Browser initialize
       setTimeout(function () {
         if (page === undefined) {
           page = new Vue({
             el: '#page',
             components: {
               vm
             }
           })
         }
       }, 500)
    </script>
grapewheel commented 5 years ago

你可以修改vant为CDN引入,avvw只是一个脚手架,可以随意修改,例子采用按需引入的原因是减少发布包体积和提高加载速度

grapewheel commented 5 years ago

发布dist的资源文件可以分目录,其实这个分不分目录不会影响最终发布包的大小和运行,只是程序员自身对于发布包的目录结构要求而已,发布包是机器所关心的,而不是程序员关心的,程序员一般只关心src模块化源文件

grapewheel commented 5 years ago

我看你修改的webpack配置更多全局引入 css 和 js,其实不推荐这样做,因为apicloud的运行机制是一个page就是一个虚拟浏览器,那么你放在全局加载,每个page都会加载,但并不是每个page都会使用所有模块,会影响运行效率的,所有推荐你使用page上按需import来达到按需加载,适合模块化设计思想