0
1
Fork 0

Webpack caching

This commit is contained in:
Juan Ferrer Toribio 2017-03-02 11:01:29 +01:00
parent 1a5bcf2bd2
commit b7ec06ffdc
27 changed files with 237 additions and 212 deletions

3
.eslintrc.yml Normal file
View File

@ -0,0 +1,3 @@
extends: eslint:recommended
rules:
no-undef: 0

2
.gitignore vendored
View File

@ -1 +1,3 @@
node_modules node_modules
npm-debug.log
build

20
app.js
View File

@ -1,18 +1,21 @@
var host = window.location.host.split(':')[0]; var assetsPath;
if (_DEV_MODE) if (_DEV_MODE)
host = host +':8080'; {
var host = window.location.host.split(':')[0];
assetsPath = 'http://'+ host +':'+ _DEV_SERVER_PORT +'/'+ _PUBLIC_PATH;
}
else
assetsPath = _PUBLIC_PATH;
__webpack_public_path__ = '//'+ host +'/build/'; __webpack_public_path__ = assetsPath;
require ('hedera/hedera'); require ('hedera/hedera');
window.onload = function () window.onload = function ()
{ {
Vn.Locale.init (); loadLocale (main);
var lang = Vn.Locale.language;
loadLocale (lang, main);
} }
function main (req) function main (req)
@ -26,8 +29,11 @@ function main (req)
hederaWeb.run (); hederaWeb.run ();
} }
function loadLocale (lang, cb) function loadLocale (cb)
{ {
Vn.Locale.init ();
var lang = Vn.Locale.language;
switch (lang) switch (lang)
{ {
case 'ca': case 'ca':

2
debian/changelog vendored
View File

@ -1,4 +1,4 @@
hedera-web (1.390-deb8) stable; urgency=low hedera-web (2.0.1) stable; urgency=low
* Initial Release. * Initial Release.

4
debian/control vendored
View File

@ -9,8 +9,8 @@ Vcs-Git: git://www.verdnatura.es/var/git/hedera-web
Package: hedera-web Package: hedera-web
Architecture: all Architecture: all
Depends: apache2, php5-mysql, php5-mcrypt, php5-ssh2, php-vn-lib, nodejs, npm Depends: apache2, php5-mysql, php5-mcrypt, php5-ssh2, php-vn-lib, php-acpu, nodejs, npm
Suggests: php-text-captcha, php5-imap, tinymce Suggests: php-text-captcha, php5-imap
Section: misc Section: misc
Priority: optional Priority: optional
Description: Verdnatura's web page Description: Verdnatura's web page

2
debian/rules vendored
View File

@ -6,7 +6,7 @@
dh $@ dh $@
clean: clean:
npm --production run clean npm run clean
dh_clean $@ dh_clean $@
build: build:

View File

@ -11,4 +11,3 @@ const _DEV_MODE = TRUE;
const _CONFIG_DIR = __DIR__.'/../../.config'; const _CONFIG_DIR = __DIR__.'/../../.config';
const _LOG_DIR = '/tmp'; const _LOG_DIR = '/tmp';
const _DATA_DIR = '/tmp'; const _DATA_DIR = '/tmp';

View File

@ -189,7 +189,6 @@
.item-info .producer .item-info .producer
{ {
text-transform: uppercase; text-transform: uppercase;
font-weight: bold;
padding: 0; padding: 0;
padding-bottom: .2em; padding-bottom: .2em;
font-size: 1em; font-size: 1em;

View File

@ -1,17 +1,21 @@
{ {
"name": "hedera-web", "name": "hedera-web",
"version": "1.0.0", "version": "2.0.1",
"description": "Verdnatura web page", "description": "Verdnatura web page",
"devDependencies": { "devDependencies": {
"assets-webpack-plugin": "^3.5.1",
"bundle-loader": "^0.5.4", "bundle-loader": "^0.5.4",
"css-loader": "^0.25.0", "css-loader": "^0.25.0",
"eslint": "^3.16.1",
"file-loader": "^0.9.0", "file-loader": "^0.9.0",
"json-loader": "^0.5.4", "json-loader": "^0.5.4",
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",
"style-loader": "^0.13.1", "style-loader": "^0.13.1",
"url-loader": "^0.5.7", "url-loader": "^0.5.7",
"webpack": "^1.13.3", "webpack": "^2.2.0",
"webpack-dev-server": "^1.16.2" "webpack-chunk-hash": "^0.4.0",
"webpack-dev-server": "^2.2.0",
"webpack-merge": "^3.0.0"
}, },
"dependencies": { "dependencies": {
"mootools": "^1.5.2", "mootools": "^1.5.2",
@ -19,7 +23,7 @@
}, },
"scripts": { "scripts": {
"dev": "webpack-dev-server --progress --colors --hot", "dev": "webpack-dev-server --progress --colors --hot",
"build": "rm -f build/* ; webpack --progress --colors", "build": "rm -rf build/ ; webpack --progress --colors",
"clean": "rm -rf build/" "clean": "rm -rf build/"
} }
} }

View File

@ -1,9 +0,0 @@
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-49049601-1', 'verdnatura.es');
ga('send', 'pageview');
</script>

View File

@ -1,17 +0,0 @@
<?php
use Vn\Lib\Locale;
echo '<meta name="content-language" content="'. Locale::get () .'"/>'."\n\t\t";
if ($result = $db->query ('SELECT name, content FROM metatag'))
{
while ($row = $result->fetch_assoc ())
echo "<meta name=\"{$row['name']}\" content=\"{$row['content']}\"/>\n\t\t";
$result->free ();
}
$url = _DEV_MODE ? "http://{$_SERVER['SERVER_NAME']}:8080/" : '';
$this->includeJs ("{$url}build/hedera-web.js");

View File

@ -1,5 +1,50 @@
<!DOCTYPE html> <?php
$lang = Vn\Lib\Locale::get ();
$result = $db->query('SELECT name, content FROM metatag');
$wpConfig = json_decode (file_get_contents ('webpack.config.json'));
$buildDir = $wpConfig->buildDir;
$devServerPort = $wpConfig->devServerPort;
$host = $_SERVER['SERVER_NAME'];
$assets = new stdClass();
if (!_DEV_MODE)
{
$wpAssets = json_decode (file_get_contents ("$buildDir/webpack-assets.json"));
$manifestJs = $wpAssets->manifest->js;
$mainJs = $wpAssets->main->js;
unset ($wpAssets->manifest);
unset ($wpAssets->main);
foreach ($wpAssets as $name => $asset)
if (property_exists ($asset, 'js'))
$assets->$name = $asset->js;
}
else
{
$devServerPath = "http://$host:$devServerPort/$buildDir";
$manifestJs = "$devServerPath/manifest.js";
$mainJs = "$devServerPath/main.js";
unset ($wpConfig->entry->main);
foreach ($wpConfig->entry as $asset => $files)
$assets->$asset = "$devServerPath/$asset.js";
}
$jsFiles = [];
$jsFiles[] = $manifestJs;
foreach ($assets as $jsFile)
$jsFiles[] = $jsFile;
$jsFiles[] = $mainJs;
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"> <html xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
@ -11,7 +56,15 @@
<link rel="icon" type="image/svg+xml" href="image/icon.svg" sizes="any"/> <link rel="icon" type="image/svg+xml" href="image/icon.svg" sizes="any"/>
<link rel="manifest" href="manifest.json"/> <link rel="manifest" href="manifest.json"/>
<meta name="theme-color" content="#009688"/> <meta name="theme-color" content="#009688"/>
<?php include 'head.php' ?> <meta name="content-language" content="<?=$lang?>"/>
<?php while ($row = $result->fetch_object()): ?>
<meta name="<?=$row->name?>" content="<?=$row->content?>"/>
<?php endwhile ?>
<?php foreach ($jsFiles as $js): ?>
<script type="text/javascript" src="<?=$js?>"></script>
<?php endforeach ?>
<title>Verdnatura</title> <title>Verdnatura</title>
</head> </head>

View File

@ -1,4 +0,0 @@
{
"PaymentComplete": "Pagament acabat, ja pots tornar a la nostra pàgina web."
,"ReturnToWeb": "Tornar a Verdnatura"
}

View File

@ -1,4 +0,0 @@
{
"PaymentComplete": "Payment completed, you can return to our website."
,"ReturnToWeb": "Back to Verdnatura"
}

View File

@ -1,4 +0,0 @@
{
"PaymentComplete": "Pago terminado, ya puedes volver a nuestra página web."
,"ReturnToWeb": "Volver a Verdnatura"
}

View File

@ -1,4 +0,0 @@
{
"PaymentComplete": "Paiement terminé, merci par votre confiance, maintenant vous pouvez revenir à notre site."
,"ReturnToWeb": "Retour au Verdnatura"
}

View File

@ -1,4 +0,0 @@
{
"PaymentComplete": "Payment completed, you can return to our website."
,"ReturnToWeb": "Back to Verdnatura"
}

View File

@ -1,4 +0,0 @@
{
"PaymentComplete": "Pagamento terminado, já podes voltar a nossa página web."
,"ReturnToWeb": "Voltar a Verdnatura"
}

View File

@ -1,16 +0,0 @@
*
{
font-family: 'Roboto';
font-size: 10pt;
}
div
{
position: absolute;
width: 48em;
height: 10em;
margin-left: -24em;
margin-top: -5em;
top: 50%;
left: 50%;
text-align: center;
}

View File

@ -1,22 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="user-scalable=no"/>
<link href="http://fonts.googleapis.com/css?family=Roboto" rel="stylesheet" type="text/css"/>
<link rel="stylesheet" type="text/css" href="<?=$dir?>/style.css"/>
<title>Verdnatura</title>
</head>
<body>
<div>
<img src="image/logo.svg" alt="Verdnatura"/>
<p>
<?=s('PaymentComplete')?>
</p>
<p>
<a href="?page=web#!module=orders"><?=s('ReturnToWeb')?></a>
</p>
</div>
</body>
</html>

View File

@ -58,6 +58,7 @@ class Mail extends Vn\Lib\Method
foreach ($mailList as $mailTo) foreach ($mailList as $mailTo)
$mail->AddAddress ($mailTo); $mail->AddAddress ($mailTo);
$mail->IsHTML (TRUE);
$mail->Subject = $row['subject']; $mail->Subject = $row['subject'];
$mail->Body = ' '. $row['text']; $mail->Body = ' '. $row['text'];
$mail->CharSet = 'UTF-8'; $mail->CharSet = 'UTF-8';

View File

@ -2,6 +2,8 @@
namespace Vn\Web; namespace Vn\Web;
require_once __DIR__.'/html.php';
use Vn\Lib\Locale; use Vn\Lib\Locale;
/** /**
@ -101,43 +103,9 @@ class HtmlService extends Service
exit (0); exit (0);
} }
function getUrl ($fileName)
{
/* if (file_exists ($fileName))
$mTime = '?'. strftime ('%G%m%d%H%M%S', filemtime ($fileName));
else
*/ $mTime = '?'. $this->getVersion ();
return $fileName.$mTime;
}
function includeJs ($fileName)
{
echo '<script type="text/javascript" src="'. $this->getUrl ($fileName) .'"></script>'."\n\t\t";
}
function includeLib ($libName)
{
$args = func_get_args ();
$localeJs = 'locale/'. Locale::get () .'/js/'. $libName .'.js';
if (file_exists ($localeJs))
$this->includeJs ($localeJs);
for ($i = 1; $i < count ($args); $i++)
$this->includeJs ("js/$libName/{$args[$i]}.js");
}
function includeCss ($fileName)
{
echo '<link rel="stylesheet" type="text/css" href="'. $this->getUrl ($fileName) .'"/>'."\n\t\t";
}
function isMobile () function isMobile ()
{ {
$re = '/(Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone)/i'; $re = '/(Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone)/i';
return preg_match ($re, $_SERVER['HTTP_USER_AGENT']); return preg_match ($re, $_SERVER['HTTP_USER_AGENT']);
} }
} }

39
web/html.php Normal file
View File

@ -0,0 +1,39 @@
<?php
function getUrl ($fileName)
{
if (file_exists ($fileName))
{
$hashes = apc_fetch ("$appName.hashes", $success);
if (!$success)
{
apc_store ("$appName.version", $version);
$hashes = [];
}
if (!isset ($hashes[$fileName]))
{
$hash = md5_file($fileName);
$hashes[$fileName] = $hash;
}
else
$hash = $hashes[$fileName];
$mTime = "?$hash";
}
else
$mTime = '';
return $fileName.$mTime;
}
function js ($fileName)
{
return '<script type="text/javascript" src="'. getUrl ($fileName) .'"></script>'."\n";
}
function css ($fileName)
{
return '<link rel="stylesheet" type="text/css" href="'. getUrl ($fileName) .'"/>'."\n";
}

View File

@ -18,15 +18,7 @@ class JsonService extends RestService
set_exception_handler ([$this, 'exceptionHandler']); set_exception_handler ([$this, 'exceptionHandler']);
$this->startSession (); $this->startSession ();
$this->checkVersion ();
// Checks the client version
if (!empty ($_COOKIE['vnVersion']))
$clientVersion = (int) $_COOKIE['vnVersion'];
if (isset ($clientVersion)
&& $clientVersion < $this->getVersion ())
throw new OutdatedVersionException ();
$json = $this->loadMethod (__NAMESPACE__.'\JsonRequest'); $json = $this->loadMethod (__NAMESPACE__.'\JsonRequest');
$this->replyJson ($json); $this->replyJson ($json);

View File

@ -295,6 +295,46 @@ abstract class Service
return $res; return $res;
} }
/**
* Obtains the application version number. It is extracted and
* cached from package.json file.
*
* @return string The version number
*/
function getVersion ()
{
$appName = $this->app->getName ();
$version = apc_fetch("$appName.version", $success);
if (!$success)
{
if (file_exists ('package.json'))
{
$package = json_decode (file_get_contents ('package.json'));
$version = $package->version;
}
else
$version = "0.0.0";
apc_store ("$appName.version", $version);
}
return $version;
}
/**
* Checks the client version.
*/
function checkVersion ()
{
if (!empty ($_COOKIE['vnVersion']))
$clientVersion = $_COOKIE['vnVersion'];
if (isset ($clientVersion)
&& $clientVersion < $this->getVersion ())
throw new OutdatedVersionException ();
}
/** /**
* Checks if the HTTP connection is secure. * Checks if the HTTP connection is secure.
* *
@ -315,33 +355,5 @@ abstract class Service
$proto = $this->isHttps () ? 'https' : 'http'; $proto = $this->isHttps () ? 'https' : 'http';
return "$proto://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}"; return "$proto://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}";
} }
/**
* Obtains the application version number. It is based on de last
* modification date of the main script.
*
* @return string The version number
*/
function getVersion ()
{
return (int) strftime ('%G%m%d%H%M%S',
filectime ($_SERVER['SCRIPT_FILENAME']));
}
/**
* Obtains the relative path to document root from an absolute path.
*
* @return string The relative path
*/
function getDir ($absoluteDir)
{
error_log ("Absolute: $absoluteDir");
error_log ("Root: {$_SERVER['DOCUMENT_ROOT']}");
error_log ("Script: {$_SERVER['SCRIPT_FILENAME']}");
error_log ("Self: {$_SERVER['PHP_SELF']}");
$rootLen = strlen ($_SERVER['DOCUMENT_ROOT']);
return substr ($absoluteDir, $rootLen);
}
} }

View File

@ -1,53 +1,80 @@
var webpack = require ('webpack');
var path = require ('path'); var path = require ('path');
var webpack = require ('webpack');
var AssetsWebpackPlugin = require ('assets-webpack-plugin');
var WebpackChunkHash = require ('webpack-chunk-hash');
var merge = require ('webpack-merge');
var wpConfig = require ('./webpack.config.json');
var devMode = process.env.NODE_ENV !== 'production'; var devMode = process.env.NODE_ENV !== 'production';
var outputPath = path.join (__dirname, wpConfig.buildDir);
var publicPath = wpConfig.buildDir +'/';
var config = { var baseConfig = {
entry: ['./app.js'], entry: wpConfig.entry,
output: { output: {
path: path.join (__dirname, 'build'), path: outputPath,
filename: 'hedera-web.js', publicPath: publicPath,
chunkFilename: 'chunk.[id].[chunkhash].js', filename: '[name].js',
publicPath: 'build/' chunkFilename: 'chunk.[id].js'
}, },
module: { module: {
loaders: [ rules: [
{ test: /\.css$/, loader: 'style!css' }, { test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.json$/, loader: 'json' }, { test: /\.xml$/, loader: 'raw-loader' },
{ test: /\.xml$/, loader: 'raw' }, { test: /\.ttf$/, loader: 'file-loader' }
{ test: /\.ttf$/, loader: 'file' }
] ]
}, },
resolve: { resolve: {
modulesDirectories: [__dirname +'/js', __dirname, 'node_modules'], modules: [
fallback: process.env.NODE_PATH, __dirname +'/js',
}, __dirname,
resolveLoader: { 'node_modules',
fallback: process.env.NODE_PATH '/usr/lib/node_modules'
]
}, },
plugins: [ plugins: [
new webpack.DefinePlugin ({ _DEV_MODE: devMode }) new webpack.DefinePlugin ({
_DEV_MODE: devMode,
_DEV_SERVER_PORT: wpConfig.devServerPort,
_PUBLIC_PATH: JSON.stringify (publicPath)
}),
new webpack.optimize.CommonsChunkPlugin ({
names: ['vendor', 'manifest']
})
]
};
var prodConfig = {
output: {
filename: '[name].[chunkhash].js',
chunkFilename: 'chunk.[id].[chunkhash].js'
},
plugins: [
new webpack.optimize.UglifyJsPlugin ({
minimize: true,
compress: { warnings: false }
}),
new AssetsWebpackPlugin ({
path: outputPath
}),
new webpack.HashedModuleIdsPlugin (),
new WebpackChunkHash ()
],
devtool: 'source-map'
};
var devConfig = {
plugins: [
new webpack.NamedModulesPlugin ()
], ],
devServer: { devServer: {
inline: true,
host: '0.0.0.0', host: '0.0.0.0',
headers: { "Access-Control-Allow-Origin": "*" } port: wpConfig.devServerPort,
headers: { "Access-Control-Allow-Origin": "*" },
stats: { chunks: false }
}, },
devtool: 'eval-source-map' devtool: 'eval-source-map'
}; };
if (!devMode) var mrgConfig = devMode ? devConfig : prodConfig;
{ module.exports = merge (baseConfig, mrgConfig);
config.plugins.push (
new webpack.optimize.UglifyJsPlugin ({
minimize: true,
compress: { warnings: false }
})
);
config.devtool = 'source-map';
}
module.exports = config;

8
webpack.config.json Normal file
View File

@ -0,0 +1,8 @@
{
"buildDir": "build",
"devServerPort": 9000,
"entry": {
"main": "./app.js",
"vendor": "mootools"
}
}