前言

Weex是使用Vue和WebPack进行项目配置的。Weex创建的项目默认是只有一个入口的,也就是说,是单页面应用。对于移动开发来说,使用单页面(使用vue-router)是没有原生的页面跳转效果。在Weex的官方文档中,Weex提供了navigator内置模块来实现Web端前进、后退页面,以及iOS/Android的navigator导航效果。

Weex的多页面配置

我使用的是最近的weex创建的项目,下面是weex的项目结构。


我们打开weebpack.config.js。

// You can see all the config in `./configs`.
const  buildPlugins = require('./configs/plugin');
let webpackConfig;
module.exports = env => {
  switch (env.NODE_ENV) {
    case 'prod':
    case 'production':
      webpackConfig = require('./configs/webpack.prod.conf');
      break;
    case 'test':
    case 'testing':
      webpackConfig = require('./configs/webpack.test.conf');
      break;
    case 'plugin':
      buildPlugins();
    case 'common':
      webpackConfig = require('./configs/webpack.common.conf');
      break;
    case 'release':
      webpackConfig = require('./configs/webpack.release.conf');
      break;
    case 'dev':
    case 'development':
    default:
      webpackConfig = require('./configs/webpack.dev.conf');
  }
  return webpackConfig;
}

可以看到webpackConfig的配置根据特定环境放在不同的文件。

我们打开configs文件夹下的webpack.common.conf.js,这个文件是配置weex和web的入口。weex把移动端和web端的webpack入口和出口配置分为weex和web。

weexConfig的入口和出口配置(iOS/Android)

我们在configs/webpack.common.conf.js下找到weexEntry。

const weexEntry = {
  'index': helper.root('entry.js'),
  'login': helper.root('login.js'),
}

这里我已经创建了src/login.js文件,这个文件和src/entry.js的内容是一样的,只是对应的vue不同。和entry.js一样都会在使用web/index.html作为页面渲染。下面是src/login.js。

/*global Vue*/

/* weex initialized here, please do not move this line */
const router = require('./router');
const App = require('@/login.vue');
/* eslint-disable no-new */
new Vue(Vue.util.extend({el: '#root', router}, App));
router.push('/');


以上就是weexConfig的入口配置(iOS/Android的webpack入口配置)。weex已经帮我们配置好weexConfig的出口配置。

const weexConfig = {
  entry: weexEntry,
  output: {
    path: path.join(__dirname, '../dist'),
    filename: '[name].js'
  },
  /**
   * Options affecting the resolving of modules.
   * See http://webpack.github.io/docs/configuration.html#resolve
   */
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      '@': helper.resolve('src')
    }
  },
  /*
   * Options affecting the resolving of modules.
   *
   * See: http://webpack.github.io/docs/configuration.html#module
   */
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [{
          loader: 'babel-loader'
        }],
        exclude: config.excludeModuleReg
      },
      {
        test: /\.vue(\?[^?]+)?$/,
        use: [{
          loader: 'weex-loader',
          options: vueLoaderConfig({useVue: false})
        }],
        exclude: config.excludeModuleReg
      }
    ]
  },
webConfig的入口和出口配置(web)

我们在configs/webpack.common.conf.js下找到webEntry。

// The entry file for web needs to add some library. such as vue, weex-vue-render
// 1. src/entry.js 
// import Vue from 'vue';
// import weex from 'weex-vue-render';
// weex.init(Vue);
// 2. src/router/index.js
// import Vue from 'vue'
const webEntry = getEntryFile();

上面有一些注释,说明webConfig的入口文件需要导入Vue和weex-vue-render模块。我们找到getEntryFile()函数。

const getEntryFile = () => {
  const entryFile = path.join(vueWebTemp, config.entryFilePath)
  const routerFile = path.join(vueWebTemp, config.routerFilePath)
  fs.outputFileSync(entryFile, getEntryFileContent(helper.root(config.entryFilePath), routerFile));
  fs.outputFileSync(routerFile, getRouterFileContent(helper.root(config.routerFilePath)));
  const loginFilePath = 'login.js'
  const loginFile = path.join(vueWebTemp, loginFilePath)
  fs.outputFileSync(loginFile, getEntryFileContent(helper.root(loginFilePath), routerFile));

  return {
    index: entryFile,
    login: loginFile,
  }
}

这个函数的entryFile使用的是path/vueWebTemp/config.entryFilePath的文件,routerFile使用的是path/vueWebTemp/config.routerFilePath的文件。

我们找到vueWebTemp和config.entryFilePath。

const path = require('path');
const fs = require('fs-extra');
const webpack = require('webpack');
const config = require('./config');
const helper = require('./helper');
const glob = require('glob');
const vueLoaderConfig = require('./vue-loader.conf');
const vueWebTemp = helper.rootNode(config.templateDir);

config是当前目录下的config.js文件。下面是config.js的部分代码。

const path = require('path');
const ROOT = path.resolve(__dirname, '..');
const ip = require('ip').address();
const config = {
  root: ROOT,
  // webpack-dev-server
  pluginConfigPath: 'plugins/plugins.json',
  pluginFilePath: 'plugins/plugins.js',
  // router
  routerFilePath: 'router.js',
  // common
  templateDir: '.temp',
  entryFilePath: 'entry.js',
  // Module exclude from compile process
  excludeModuleReg: /node_modules(?!(\/|\\).*(weex).*)/,

我们看到templateDir是项目中的.temp文件,entryFilePath是entry.js,routerFilePath是router.js。

在getEntryFile()的entryFile就是项目下的.temp/entry.js。routerFile就是项目下的.temp/router.js。


我们按照上面的例子,创建login.js的webConfig入口文件。下面是login.js代码,它和entry.js的代码是一样的,只是对于的vue不同。

import Vue from 'vue'
import weex from 'weex-vue-render'
/*global Vue*/

weex.init(Vue)
/* weex initialized here, please do not move this line */
const router = require('./router');
const App = require('@/login.vue');
/* eslint-disable no-new */
new Vue(Vue.util.extend({el: '#root', router}, App));
router.push('/');

我们看到之前注释说明需要导入的vue和weex-vue-render模块。

按照getEntryFile()函数的指示,我们需要把入口文件和router文件同步到src目录的入口文件和router文件内容。(helper的root是src文件夹)。以下是helper.js的代码内容。

// Helper functions
const path = require('path');
const ROOT = path.resolve(__dirname, '..');

const root = (args) => {
  return path.join(ROOT, 'src', args);
}
const rootNode = (args) => {
  return path.join(ROOT, args);
}

const resolve = (dir) => {
  return path.join(__dirname, '..', dir)
}

module.exports = {
  root,
  rootNode,
  resolve
}

由于weex之前已经帮我们在src创建了entry.js和router.js,我们之前在配置weexConfig时已经创建了login.js。所以这段代码是把.temp文件和src的文件内容同步。最后我们在getEntryFile()返回我们的loginFile入口文件。

以上就是webConfig的入口配置,weex已经帮我们配置好webConfig的出口配置。

// Config for compile jsbundle for web.
const webConfig = {
  entry: Object.assign(webEntry, {
    'vendor': [path.resolve('node_modules/phantom-limb/index.js')]
  }),
  output: {
    path: helper.rootNode('./dist'),
    filename: '[name].web.js'
  },
编译src文件到dist文件

我们需要编译src文件到dist文件才能生效。在命令行输入weex compile src dist编译src文件夹到dist文件夹。

进行navigator跳转

由于web和iOS/Android是分开配置的,所以它们的URL分别对应web的http跳转和iOS/Android生成的本地文件的js跳转。

methods: {
    login () {
      navigator.push({url:this.getJumpBaseUrl('login')})
    },
    getJumpBaseUrl(toUrl) {  
        var bundleUrl = weex.config.bundleUrl;  
        bundleUrl = new String(bundleUrl);  
        var nativeBase;  
        var native;  
        if (WXEnvironment.platform === 'Android') {  
            nativeBase = 'file://assets/dist/';  
            native = nativeBase + toUrl + ".js";  
        } else if (WXEnvironment.platform === 'iOS') {  
            nativeBase = bundleUrl.substring(0, bundleUrl.lastIndexOf('/') + 1);  
            native = nativeBase + toUrl + ".js";  
        } else {  
            var host = 'localhost:8081';  
            var matches = /\/\/([^\/]+?)\//.exec(bundleUrl);  
            if (matches && matches.length >= 2) {  
                host = matches[1];  
            }  
  
            //此处需注意一下,tabbar 用的直接是jsbundle 的路径,但是navigator是直接跳转到新页面上的.  
            if (typeof window === 'object') {  
                nativeBase = 'http://' + host + '/';  
            } else {  
                nativeBase = 'http://' + host + '/';  
            }  
  
            native = nativeBase + toUrl + ".html";  
        }  
        return native;  
    }  
  }




Logo

前往低代码交流专区

更多推荐