我正在寻找一种让我的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
答案 0 :(得分:1)
这是一个示例项目,演示如何让Aurelia在cordova上运行(这是PhoneGap的底层引擎):https://github.com/arjendeblok/aurelia-cordova-skeleton
一些关键步骤(来自自述文件):
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;
webpack.config.js
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;
index.ejs
<!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;
src/cordova-events.ts
export class CordovaEvents {
waitForDeviceReady(): Promise<boolean> {
let p = new Promise<boolean>((resolve, reject) => {
document.addEventListener('deviceready', () => {
resolve(true);
}, false);
});
return p;
}
}
&#13;
src/main.ts
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;