Aurelia Webpack捆绑包不使用PhoneGap

时间:2018-04-30 09:27:41

标签: webpack aurelia phonegap

我正在寻找一种让我的Aurelia / ESNext / Webpack应用程序与PhoneGap(Android版本)配合使用的方法。 捆绑的文件进入" www"夹。 查看检查器时,似乎webpack服务器在手机上运行应用程序时正在从错误的文件夹中请求一些文件。

知道如何正确配置Aurelia / Webpack以使其正常工作吗?

这是我的webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const project = require('./aurelia_project/aurelia.json');
const { AureliaPlugin, ModuleDependenciesPlugin } = require('aurelia-webpack-plugin');
const { optimize: { CommonsChunkPlugin, UglifyJsPlugin }, ProvidePlugin } = require('webpack');

// config helpers:
const ensureArray = (config) => config && (Array.isArray(config) ? config : [config]) || [];
const when = (condition, config, negativeConfig) =>
  condition ? ensureArray(config) : ensureArray(negativeConfig);

// primary config:
const title = 'App';
const outDir = path.resolve(__dirname, project.platform.output);
const srcDir = path.resolve(__dirname, 'src');
const nodeModulesDir = path.resolve(__dirname, 'node_modules');
const baseUrl = '/';

const cssRules = [
  { loader: 'css-loader' },
];

module.exports = ({production, server, extractCss, coverage, platform} = {}) => ({
  resolve: {
    extensions: ['.js'],
    modules: [srcDir, 'node_modules'],
  },
  entry: {
    app: ['aurelia-bootstrapper'],
    vendor: ['bluebird'],
  },
  output: {
    path: outDir,
    publicPath: (platform || 'browser') === 'mobile' ? './' : baseUrl,
    filename: production ? '[name].[chunkhash].bundle.js' : '[name].[hash].bundle.js',
    sourceMapFilename: production ? '[name].[chunkhash].bundle.map' : '[name].[hash].bundle.map',
    chunkFilename: production ? '[name].[chunkhash].chunk.js' : '[name].[hash].chunk.js'
  },
  devServer: {
    contentBase: outDir,
    // serve index.html for all 404 (required for push-state)
    historyApiFallback: true
  },
  devtool: production ? 'nosources-source-map' : 'cheap-module-eval-source-map',
  module: {
    rules: [
      // CSS required in JS/TS files should use the style-loader that auto-injects it into the website
      // only when the issuer is a .js/.ts file, so the loaders are not applied inside html templates
      {
        test: /\.css$/i,
        issuer: [{ not: [{ test: /\.html$/i }] }],
        use: extractCss ? ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: cssRules
        }) : ['style-loader', ...cssRules],
      },
      {
        test: /\.css$/i,
        issuer: [{ test: /\.html$/i }],
        // CSS required in templates cannot be extracted safely
        // because Aurelia would try to require it again in runtime
        use: cssRules
      },
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
        issuer: /\.[tj]s$/i
      },
      {
        test: /\.scss$/,
        use: ['css-loader', 'sass-loader'],
        issuer: /\.html?$/i
      },
      { test: /\.html$/i, loader: 'html-loader' },
      { test: /\.js$/i, loader: 'babel-loader', exclude: nodeModulesDir,
        options: coverage ? { sourceMap: 'inline', plugins: [ 'istanbul' ] } : {},
      },
      { test: /\.json$/i, loader: 'json-loader' },
      // use Bluebird as the global Promise implementation:
      { test: /[\/\\]node_modules[\/\\]bluebird[\/\\].+\.js$/, loader: 'expose-loader?Promise' },
      // embed small images and fonts as Data Urls and larger ones as files:
      { test: /\.(png|gif|jpg|cur)$/i, loader: 'url-loader', options: { limit: 8192 } },
      { test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff2' } },
      { test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff' } },
      // load these fonts normally, as files:
      { test: /\.(ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'file-loader' },
    ]
  },
  plugins: [
    new AureliaPlugin(),
    new ProvidePlugin({
      'Promise': 'bluebird'
    }),
    new ModuleDependenciesPlugin({
      'aurelia-testing': [ './compile-spy', './view-spy' ]
    }),
    new HtmlWebpackPlugin({
      template: 'index.ejs',
      metadata: {
        // available in index.ejs //
        title, server, baseUrl
      }
    }),
    ...when(extractCss, new ExtractTextPlugin({
      filename: production ? '[contenthash].css' : '[id].css',
      allChunks: true
    })),
    ...when(production, new CommonsChunkPlugin({
      name: ['common']
    })),
    ...when(true, new CopyWebpackPlugin([
      { from: 'src/static', to: 'static', ignore: ['*.sass', '*.scss'] },
      { from: 'src/res', to: 'res' }
    ])),
    ...when(production, new UglifyJsPlugin({
      sourceMap: true
    }))
  ]
});

以下是我的检查员的截图: Inspector screenshot

1 个答案:

答案 0 :(得分:1)

这是一个示例项目,演示如何让Aurelia在cordova上运行(这是PhoneGap的底层引擎):https://github.com/arjendeblok/aurelia-cordova-skeleton

一些关键步骤(来自自述文件):

先决条件

  • 的NodeJS
  • 科尔多瓦
  • 任何特定于平台的工具,如Android Studio

安装

npm install之后

  • cordova platform add browser用于将浏览器平台添加到cordova。
  • cordova platform add android用于将android平台添加到cordova。

以开发模式运行

npm build之后(带开发选项):

  • cordova platform run browser用于在浏览器中运行该应用。
  • cordova platform run android用于在Android中运行应用。

以生产模式运行

npm build之后(带有制作选项):

  • cordova platform build android

文件

如果github存储库消失

config.xml



<?xml version='1.0' encoding='utf-8'?>
<widget id="io.cordova.hellocordova" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>HelloCordova</name>
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
    <author email="dev@cordova.apache.org" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <plugin name="cordova-plugin-whitelist" spec="1" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
    </platform>
</widget>
&#13;
&#13;
&#13;

webpack.config.js

&#13;
&#13;
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { AureliaPlugin } = require('aurelia-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractCSS = new ExtractTextPlugin('app/app.css');
const bundleOutputDir = './www';

module.exports = ({ prod, cordova } = {}) => {
    const isDevBuild = !prod;
    const isCordova = cordova || false;

    return [{
        resolve: {
            extensions: ['.ts', '.js'],
            modules: ['src', 'node_modules'] // .map(x => path.resolve(x))
        },
        entry: {
            'app': 'aurelia-bootstrapper'
        },
        output: {
            path: path.resolve(bundleOutputDir),
            publicPath: '/',
            filename: 'app/app.js'
        },
        devServer: {
            contentBase: './www'
        },
        module: {
            rules: [
                { test: /\.ts$/i, include: /src/, use: 'ts-loader' },
                { test: /\.html$/i, use: 'html-loader' },
                {
                    test: /\.css$/i, use: isDevBuild ?
                        ['style-loader', 'css-loader'] :
                        extractCSS.extract('css-loader?minimize')
                },
                { test: /\.(png|jpg|jpeg|gif|svg|ttf|eot)$/, use: 'url-loader?limit=25000' },
                { test: /\.woff$/, use: "url-loader?prefix=font/&limit=5000&mimetype=application/font-woff" },
                { test: /\.woff2$/, use: "url-loader?prefix=font/&limit=5000&mimetype=application/font-woff2" }
            ]
        },

        plugins: [
            extractCSS,
            new webpack.DefinePlugin({ IS_DEV_BUILD: JSON.stringify(isDevBuild), IS_CORDOVA: JSON.stringify(isCordova) }),
            new AureliaPlugin({ aureliaApp: 'main', dist: 'native-modules' }),
            new HtmlWebpackPlugin({
                template: 'index.ejs',
                minify: prod ? {
                    removeComments: true,
                    collapseWhitespace: true
                } : undefined,
                metadata: {
                   prod, cordova
                }
            })
        ].concat(isDevBuild ? [
            new webpack.SourceMapDevToolPlugin({
                filename: '[file].map', // Remove this line if you prefer inline source maps
                moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]')  // Point sourcemap entries to the original file locations on disk
            })
        ] : [])
    }];
};
&#13;
&#13;
&#13;

index.ejs

&#13;
&#13;
<!DOCTYPE html>
<html>
<head>
    <!--
        Customize this policy to fit your own app's needs. For more guidance, see:
            https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy
        Some notes:
            * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication
            * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
            * Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
                * Enable inline JS: add 'unsafe-inline' to default-src
        -->
<% if (htmlWebpackPlugin.options.metadata.cordova) { %>
    <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
<% } %>
    <meta name="format-detection" content="telephone=no">
    <meta name="msapplication-tap-highlight" content="no">
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
    <title>Hello Cordova</title>
    <!-- imported CSS are concatenated and added automatically -->
</head>
<body aurelia-app="main">
    <p>booting...</p>
<% if (htmlWebpackPlugin.options.metadata.cordova) { %>
    <script type="text/javascript" src="cordova.js"></script>
<% } %>
    <!-- imported JS bundles are added automatically -->
</body>
</html>
&#13;
&#13;
&#13;

src/cordova-events.ts

&#13;
&#13;
export class CordovaEvents {
    waitForDeviceReady(): Promise<boolean> {
        let p = new Promise<boolean>((resolve, reject) => {
            document.addEventListener('deviceready', () => {
                resolve(true);
            }, false);
        });
        return p;
    }
}
&#13;
&#13;
&#13;

src/main.ts

&#13;
&#13;
import { Aurelia, PLATFORM } from 'aurelia-framework';
import { CordovaEvents } from './cordova-events';

declare const IS_DEV_BUILD: boolean; // The value is supplied by Webpack during the build
declare const IS_CORDOVA: boolean; // The value is supplied by Webpack during the build
export async function configure(aurelia: Aurelia) {
    if (IS_CORDOVA) {
        const cordova = new CordovaEvents();
        await cordova.waitForDeviceReady();
    }

    aurelia.use
        .standardConfiguration();

    if (IS_DEV_BUILD) {
        aurelia.use.developmentLogging();
    }

    await aurelia.start();

    await aurelia.setRoot(PLATFORM.moduleName('app'));
}
&#13;
&#13;
&#13;