博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
weex脚手架
阅读量:7035 次
发布时间:2019-06-28

本文共 11314 字,大约阅读时间需要 37 分钟。

此篇文章不要注意排版

经上级领导的要求,我们公司开始步入weex的队列,虽然现在已经处于开始阶段,但是是一个好的开始,一个艰苦的开始。

废话不多说,我们先聊一聊刚开始的整个过程

一、关于运行weex项目

npm要求5.+,因此安装了node8.7.0,自带安装了 npm 5.4.2

为了方便切换node版本,mac上我们可以安装n来管理
sudo npm n -g
n 8.7.0便已切换

为了 npm install 的速度快一点,设置淘宝镜像

npm config set registry

二、开始weex

1.安装weex: sudo npm install -g weex-toolkit

2初始化工程:weex init projectName
3.运行demo
weex src/index.vue
然后即可以使用playground app二维码扫描来查看效果了

我的weex版本:

clipboard.png

三、开始自己的脚手架

首先weex号称可以一套代码跑三端,那么我们暂且区分两端,原生和H5.

网上巴拉巴拉查询一通,可以使用vue-router写单页面,但是据说在原生APP上切换页面的时候很卡,因为是dom级别的切换,于是,查到建议使用navigator来跳转

然后,然后我们就想办法,自己封装一个router,让咱代码既兼容vue-router,也兼容原生。

以下是我的项目目录:

clipboard.png

原生端route

weex-routes.js文件

const basePath = 'http://192.168.21.75:8088/dist/views';const routeList = [    {path: '/bankList', component: basePath + '/bankList.weex.js'},    {path: '/bank', component: basePath + '/bank.weex.js'},    {path: '/home', component: basePath + '/home/home.weex.js'},    {path: '/material', component: basePath + '/home/material.weex.js'},    {path: '/user/register', component: basePath + '/user/register/index.weex.js'},    {path: '/user/modifyPassword', component: basePath + '/user/modifyPassword.index.weex.js'},];export default routeList;

web端route配置

web-routes.js文件

import bankList from 'views/bankList.vue';import bank from 'views/bank.vue';import home from 'views/home/home.vue';import material from 'views/home/material.vue';import register from 'views/user/register/index.vue';import modifyPassword from 'views/user/modifyPassword/index.vue';const routeList = [    {path: '/bankList', component: bankList},    {path: '/bank', component: bank},    {path: '/home/home', component: home},    {path: '/home/material', component: material},    {path: '/user/register', component: register},    {path: '/user/modifyPassword', component: modifyPassword},];export default routeList;

web端H5由于我们做成一个单页面,所以还需要一个入口文件

app.js文件

import VueRouter from 'vue-router';import routeList from './web-routes.js';Vue.use(VueRouter);const router = new VueRouter({    routes: routeList,    mode: 'history'});new Vue({    template: '
', router}).$mount('#root');

接下来就是我们来封装一下router了,让我们的代码兼容APP和H5端,

router.js文件

import routeList from './weex-routes';const navigator = weex.requireModule('navigator');/*** 从weex路由表中获取路由* @params route String|Object*/function getWeexRoute (route) {    const item = routeList.find(item => {        if (item.path === route.path || route === route.path) {            return item;        }    });    if (!item) {        throw new Error(`routes路由表中不存在该路径${route.path}`);    }    return item;};const routerConfig = {    install () {        // H5不需要重置router属性,直接返回        if (weex.config.env.rem) {            return;        }        const url = weex.config.bundleUrl;        const query = getQueryData(url);        Object.defineProperty(Vue.prototype, "$router", {            value: {                push (route) {                    const currentRoute = getWeexRoute(route);                    let query = '';                    if (route.query) {                        query = createQuery(route.query);                    }                    navigator.push({                        url: currentRoute.component + query,                        animated: 'true'                    });                },                back () {                    if (navigator) {                        navigator.pop();                    }                }            },            configurable: false        });        Object.defineProperty(Vue.prototype, '$route', {            configurable: false,            value: {                query: query,                fullPath: '',                name: '',                params: {},                path: '',                hash: '',            }        });    }}Vue.use(routerConfig);// object 转 URL 参数function createQuery (obj) {    let url = '?';    for (let key in obj) {        if (obj[key] !== null) {            url += (key + '=' + encodeURIComponent(obj[key]) + '&');        }    }    return url.substring(0, url.lastIndexOf('&'));};// 'xxx.js?name=aa' 转 {name: 'aa'}function getQueryData (url) {    url = url.substring(url.indexOf('.js?') + 3);    var result = {};    if (url.indexOf("?") != -1) {        var str = url.substr(1);        var strs = str.split("&");        for (var i = 0; i < strs.length; i++) {            result[strs[i].split("=")[0]] = decodeURIComponent(strs[i].split("=")[1]);        }    }    return result; };

ok基础设施已大功告成,我们需要在我们的业务代码中使用router了

// 首先需要引入我们的router.jsimport '../../router.js';this.$router.push({path: '/material', query: this.form});// 当跳转到material.vue中我们则可以直接获取url中的参数了,此法兼容原生和H5import '../../router.js';this.query = this.$route.query;

基础的配置我们已经操作完毕,接下来要配置webpack了

我们需要一个build xx.wexx.js的webpack配置
和一个web的单页的webpack配置

webpack.web.js配置

const ip = require('ip').address();const path = require('path');const chalk = require('chalk');const webpack = require('webpack');const ExtractTextPlugin = require('extract-text-webpack-plugin');console.log('server is running! Please open ' + chalk.green('http://' + ip + ':8080/'));const HtmlWebpackPlugin = require('html-webpack-plugin');const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');const isProd = process.env.NODE_ENV === 'production';module.exports = function() {    const config = {        entry: {            app: './src/app.js'        },        output: {            path: path.join(__dirname, './dist'),            filename: '[name].[hash:7].web.js',        },        resolve: {            extensions: ['*', '.vue', '.js'],            alias: {                'src': path.join(__dirname, './src'),                'views': path.join(__dirname, './src/views'),                'services': path.join(__dirname, './src/services'),                'utils': path.join(__dirname, './src/utils'),                'constants': path.join(__dirname, './src/constants'),                'assets': path.join(__dirname, './src/assets'),            }        },        devtool: 'source-map',        module: {            rules: [                {                    test: /\.vue(\?[^?]+)?$/,                    loader: 'vue-loader',                },                {                    test: /\.html$/,                    loader: 'raw-loader',                },                {                    test: /\.js$/,                    use: 'babel-loader',                    exclude: /node_modules/                }            ]        },        plugins: [            new webpack.BannerPlugin({                banner: '// { "framework": ' + ('.vue' === '.vue' ? '"Vue"' : '"Weex"') + '} \n',                raw: true,                exclude: 'Vue'            }),            new ScriptExtHtmlWebpackPlugin({                defaultAttribute: 'defer'            })        ]    };    if (!isProd) {        config.plugins.push(            new HtmlWebpackPlugin({                template: 'web/index.dev.html',                title: 'Hello Weex',                isDevServer: true,                chunksSortMode: 'dependency',                inject: 'head'            })        );        config.devServer = {            compress: true,            host: '0.0.0.0',            port: '8080',            historyApiFallback: true,            public: ip + ':8080',            watchOptions: {                aggregateTimeout: 300,                poll: 1000            }        };    } else {        // 抽取vue文件css        config.module.rules[0].options = {            loaders: {                css: ExtractTextPlugin.extract({                    use: ['css-loader'],                    fallback: 'vue-style-loader'                })            }        };        config.plugins.push(            new ExtractTextPlugin('[name].[hash:7].css'),            new HtmlWebpackPlugin({                template: 'web/index.html',                inject: true,            }),            new webpack.optimize.UglifyJsPlugin({                compress: {                    warnings: false                }            })        )    }    return config;}

原生端的webpack.config.js配置:

const pathTo = require('path');const fs = require('fs-extra');const webpack = require('webpack');const entry = {};const weexEntry = {};const vueWebTemp = 'temp';const hasPluginInstalled = fs.existsSync('./web/plugin.js');var isWin = /^win/.test(process.platform);function getEntryFileContent(entryPath, vueFilePath) {  let relativePath = pathTo.relative(pathTo.join(entryPath, '../'), vueFilePath);  let contents = '';  if (hasPluginInstalled) {    const plugindir = pathTo.resolve('./web/plugin.js');    contents = 'require(\'' + plugindir + '\') \n';  }  if (isWin) {    relativePath = relativePath.replace(/\\/g,'\\\\');  }  contents += 'var App = require(\'' + relativePath + '\')\n';  contents += 'App.el = \'#root\'\n';  contents += 'new Vue(App)\n';  return contents;}var fileType = '';function walk(dir) {  dir = dir || '.';  const directory = pathTo.join(__dirname, 'src', dir);  fs.readdirSync(directory)    .forEach((file) => {      const fullpath = pathTo.join(directory, file);      const stat = fs.statSync(fullpath);      const extname = pathTo.extname(fullpath);      if (stat.isFile() && extname === '.vue' || extname === '.we') {        if (!fileType) {          fileType = extname;        }        if (fileType && extname !== fileType) {          console.log('Error: This is not a good practice when you use ".we" and ".vue" togither!');        }        const name = pathTo.join(dir, pathTo.basename(file, extname));        if (extname === '.vue') {          const entryFile = pathTo.join(vueWebTemp, dir, pathTo.basename(file, extname) + '.js');          fs.outputFileSync(pathTo.join(entryFile), getEntryFileContent(entryFile, fullpath));                    entry[name] = pathTo.join(__dirname, entryFile) + '?entry=true';        }         if (fullpath.includes('/views')) {          weexEntry[name] = fullpath + '?entry=true';        }      } else if (stat.isDirectory() && file !== 'build' && file !== 'include') {        const subdir = pathTo.join(dir, file);        walk(subdir);      }    });}walk();// web need vue-loaderconst plugins = [  new webpack.optimize.UglifyJsPlugin({minimize: true}),  new webpack.BannerPlugin({    banner: '// { "framework": ' + (fileType === '.vue' ? '"Vue"' : '"Weex"') + '} \n',    raw: true,    exclude: 'Vue'  })];const weexConfig = {  entry: weexEntry,  output: {    path: pathTo.join(__dirname, 'dist'),    filename: '[name].weex.js',  },  module: {    rules: [      {        test: /\.js$/,        use: [{          loader: 'babel-loader',        }],        exclude: /node_modules(?!\/.*(weex).*)/      },      {        test: /\.vue(\?[^?]+)?$/,        use: [{          loader: 'weex-loader'        }]      },      {        test: /\.we(\?[^?]+)?$/,        use: [{          loader: 'weex-loader'        }]      }    ]  },  plugins: plugins,};module.exports = weexConfig;

package.json配置:

"build": "rm -rf dist && cross-env NODE_ENV=production webpack --config webpack.web.js && webpack --config webpack.config.js",    "web1": "webpack --config webpack.web.js --watch",    "web2": "webpack-dev-server --config webpack.web.js --progress --watch --open",    "web": "rm -rf dist&npm run web1&npm run web2"

打包执行 npm run build,就会把weex和H5的文件都给生产到dist目录中了

.weex文件是原生的,.css .web index.html是H5的

clipboard.png

还需要注意的地方:

由于我们也是刚开始接触weex,希望这这只是一个参考案例,毕竟我们也不是高手。

转载地址:http://bufal.baihongyu.com/

你可能感兴趣的文章
android读取手机验证码
查看>>
何时进行重构?
查看>>
centos6.2x64系统配置本地yum源
查看>>
Java Strategy 模式简介
查看>>
CDH-cdh5.8.3离线安装--Mysql5.7二进制部署
查看>>
flask request 对象
查看>>
【VMware虚拟化解决方案】Horizon-View GPU虚拟化
查看>>
Redis 对象
查看>>
Android应用程序获取ROOT权限的方法
查看>>
KVM主机在线增加硬盘爬坑记
查看>>
【Linxu学习004】Bash Shell 相关
查看>>
Linux 下的shell
查看>>
iptables 知识-filter表
查看>>
Windows平台视频显示问题
查看>>
python性能分析
查看>>
备份与还原---bacula简介
查看>>
Windows Live Writer Test
查看>>
读书笔记之顺序循环队列
查看>>
我的友情链接
查看>>
转换jdk版本
查看>>