setup webpack
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,6 +14,7 @@
|
|||||||
.idea
|
.idea
|
||||||
.project
|
.project
|
||||||
.strong-pm
|
.strong-pm
|
||||||
|
client
|
||||||
coverage
|
coverage
|
||||||
node_modules
|
node_modules
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
|
|||||||
0
client/.empty
Normal file
0
client/.empty
Normal file
@@ -1,6 +0,0 @@
|
|||||||
<head>
|
|
||||||
<title>Demo</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p>Hello World... </p>
|
|
||||||
</body>
|
|
||||||
27
package.json
27
package.json
@@ -4,30 +4,45 @@
|
|||||||
"main": "server/server.js",
|
"main": "server/server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"start": "node .",
|
"posttest": "npm run lint && nsp check",
|
||||||
"posttest": "npm run lint && nsp check"
|
"build": "rimraf client/*; NODE_ENV=production webpack --config server/config/webpack.prod.js --progress --hide-modules",
|
||||||
|
"start": "NODE_ENV=production node .",
|
||||||
|
"dev": "NODE_ENV=development nodemon -w server -w common ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"babel-core": "^6.22.1",
|
||||||
|
"babel-loader": "^6.2.10",
|
||||||
|
"babel-preset-es2015": "^6.22.0",
|
||||||
"compression": "^1.0.3",
|
"compression": "^1.0.3",
|
||||||
"cors": "^2.5.2",
|
"cors": "^2.5.2",
|
||||||
|
"favicons-webpack-plugin": "^0.0.7",
|
||||||
|
"file-loader": "^0.9.0",
|
||||||
"helmet": "^1.3.0",
|
"helmet": "^1.3.0",
|
||||||
|
"html-webpack-plugin": "^2.26.0",
|
||||||
|
"json-loader": "^0.5.4",
|
||||||
"loopback": "^3.0.0",
|
"loopback": "^3.0.0",
|
||||||
"loopback-boot": "^2.6.5",
|
"loopback-boot": "^2.6.5",
|
||||||
"loopback-component-explorer": "^4.0.0",
|
"loopback-component-explorer": "^4.0.0",
|
||||||
"strong-error-handler": "^1.0.1"
|
"strong-error-handler": "^1.0.1",
|
||||||
|
"webpack": "^2.2.0",
|
||||||
|
"webpack-dev-middleware": "^1.9.0",
|
||||||
|
"webpack-hot-middleware": "^2.15.0",
|
||||||
|
"webpack-merge": "^2.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^3.13.0",
|
"eslint": "^3.13.0",
|
||||||
|
"eslint-config-airbnb": "^14.0.0",
|
||||||
"eslint-plugin-import": "^2.2.0",
|
"eslint-plugin-import": "^2.2.0",
|
||||||
"eslint-plugin-jsx-a11y": "^3.0.2",
|
"eslint-plugin-jsx-a11y": "^3.0.2",
|
||||||
"eslint-plugin-react": "^6.9.0",
|
"eslint-plugin-react": "^6.9.0",
|
||||||
"eslint-config-airbnb": "^14.0.0",
|
"nodemon": "^1.11.0",
|
||||||
"nsp": "^2.1.0"
|
"nsp": "^2.1.0",
|
||||||
|
"rimraf": "^2.5.4"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "",
|
"type": "",
|
||||||
"url": ""
|
"url": ""
|
||||||
},
|
},
|
||||||
"license": "UNLICENSED",
|
"license": "MIT",
|
||||||
"description": "02-customer-portal"
|
"description": "02-customer-portal"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
module.exports = function enableAuthentication(server) {
|
module.exports = function enableAuthentication(server) {
|
||||||
// enable authentication
|
// enable authentication
|
||||||
// server.enableAuth();
|
// server.enableAuth();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const pingRoute = require('./routes/ping');
|
const pingRoute = require('./routes/ping');
|
||||||
|
|
||||||
module.exports = function(server) {
|
module.exports = (server) => {
|
||||||
var router = server.loopback.Router();
|
const router = server.loopback.Router();
|
||||||
|
|
||||||
// Install a `/` route that returns server status
|
// Install a `/` route that returns server status
|
||||||
// router.get('/', server.loopback.status());
|
// router.get('/', server.loopback.status());
|
||||||
|
|||||||
25
server/boot/webpack-dev.js
Normal file
25
server/boot/webpack-dev.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
const webpack = require('webpack');
|
||||||
|
const webpackMiddleware = require('webpack-dev-middleware');
|
||||||
|
const config = require('../config/webpack.dev');
|
||||||
|
|
||||||
|
const isProduction = (process.env.NODE_ENV === 'production');
|
||||||
|
|
||||||
|
module.exports = (app) => {
|
||||||
|
if (isProduction) return;
|
||||||
|
|
||||||
|
const compiler = webpack(config);
|
||||||
|
const middleware = webpackMiddleware(compiler, {
|
||||||
|
publicPath: config.output.publicPath,
|
||||||
|
contentBase: 'src',
|
||||||
|
stats: {
|
||||||
|
colors: true,
|
||||||
|
hash: false,
|
||||||
|
timings: true,
|
||||||
|
chunks: false,
|
||||||
|
chunkModules: false,
|
||||||
|
modules: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use(middleware);
|
||||||
|
};
|
||||||
13
server/boot/webpack-hmr.js
Normal file
13
server/boot/webpack-hmr.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
const webpack = require('webpack');
|
||||||
|
const webpackHotMiddleware = require('webpack-hot-middleware');
|
||||||
|
const config = require('../config/webpack.dev');
|
||||||
|
|
||||||
|
const isProduction = (process.env.NODE_ENV === 'production');
|
||||||
|
|
||||||
|
module.exports = (app) => {
|
||||||
|
if (isProduction) return;
|
||||||
|
|
||||||
|
const compiler = webpack(config);
|
||||||
|
|
||||||
|
app.use(webpackHotMiddleware(compiler));
|
||||||
|
};
|
||||||
45
server/config/webpack.base.js
Normal file
45
server/config/webpack.base.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const ROOT = path.resolve(__dirname, '..', '..');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: `${ROOT}/src/main.js`,
|
||||||
|
output: {
|
||||||
|
path: `${ROOT}/client`,
|
||||||
|
publicPath: '/',
|
||||||
|
filename: 'js/[name].js',
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.vue$/,
|
||||||
|
loader: 'vue-loader',
|
||||||
|
options: {
|
||||||
|
// vue-loader options go here
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
loader: 'babel-loader',
|
||||||
|
exclude: /node_modules/,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.json$/,
|
||||||
|
loader: 'json-loader',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|jpg|gif|svg)$/,
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[ext]?[hash]',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
src: `${ROOT}/src`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
devtool: '#eval-source-map',
|
||||||
|
};
|
||||||
27
server/config/webpack.dev.js
Normal file
27
server/config/webpack.dev.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const merge = require('webpack-merge');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const baseConfig = require('./webpack.base');
|
||||||
|
|
||||||
|
const ROOT = path.resolve(__dirname, '..', '..');
|
||||||
|
|
||||||
|
module.exports = merge(baseConfig, {
|
||||||
|
plugins: [
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env': {
|
||||||
|
NODE_ENV: '"development"',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
// generate dist index.html with correct asset hash for caching.
|
||||||
|
// you can customize output by editing /index.html
|
||||||
|
// see https://github.com/ampedandwired/html-webpack-plugin
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
filename: path.join(ROOT, 'client', 'index.html'),
|
||||||
|
template: path.join(ROOT, 'src', 'index.html'),
|
||||||
|
inject: true,
|
||||||
|
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
|
||||||
|
chunksSortMode: 'dependency',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
83
server/config/webpack.prod.js
Normal file
83
server/config/webpack.prod.js
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const merge = require('webpack-merge');
|
||||||
|
const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const baseConfig = require('./webpack.base');
|
||||||
|
|
||||||
|
const ROOT = path.resolve(__dirname, '..', '..');
|
||||||
|
|
||||||
|
module.exports = merge(baseConfig, {
|
||||||
|
output: {
|
||||||
|
filename: 'js/[name].[chunkhash].js',
|
||||||
|
},
|
||||||
|
// add sourcemaps to production build
|
||||||
|
devtool: '#source-map',
|
||||||
|
// http://vue-loader.vuejs.org/en/workflow/production.html
|
||||||
|
plugins: [
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env': {
|
||||||
|
NODE_ENV: '"production"',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
new webpack.optimize.UglifyJsPlugin({
|
||||||
|
compress: {
|
||||||
|
warnings: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
minimize: true,
|
||||||
|
}),
|
||||||
|
new FaviconsWebpackPlugin({
|
||||||
|
logo: path.join(ROOT, 'src', 'assets', 'logo.png'),
|
||||||
|
persistentCache: false,
|
||||||
|
emitStats: false,
|
||||||
|
icons: {
|
||||||
|
android: true,
|
||||||
|
appleIcon: true,
|
||||||
|
appleStartup: false,
|
||||||
|
coast: false,
|
||||||
|
favicons: true,
|
||||||
|
firefox: false,
|
||||||
|
opengraph: true,
|
||||||
|
twitter: true,
|
||||||
|
yandex: false,
|
||||||
|
windows: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
// generate dist index.html with correct asset hash for caching.
|
||||||
|
// you can customize output by editing /index.html
|
||||||
|
// see https://github.com/ampedandwired/html-webpack-plugin
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
filename: path.join(ROOT, 'client', 'index.html'),
|
||||||
|
template: path.join(ROOT, 'src', 'index.html'),
|
||||||
|
inject: true,
|
||||||
|
minify: {
|
||||||
|
removeComments: true,
|
||||||
|
// more options:
|
||||||
|
// https://github.com/kangax/html-minifier#options-quick-reference
|
||||||
|
},
|
||||||
|
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
|
||||||
|
chunksSortMode: 'dependency',
|
||||||
|
}),
|
||||||
|
// split vendor js into its own file
|
||||||
|
new webpack.optimize.CommonsChunkPlugin({
|
||||||
|
name: 'vendor',
|
||||||
|
minChunks(module) {
|
||||||
|
// any required modules inside node_modules are extracted to vendor
|
||||||
|
const nodeModules = path.join(ROOT, 'node_modules');
|
||||||
|
return (
|
||||||
|
module.resource &&
|
||||||
|
/\.js$/.test(module.resource) &&
|
||||||
|
module.resource.indexOf(nodeModules) === 0
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
// extract webpack runtime and module manifest to its own file in order to
|
||||||
|
// prevent vendor hash from being updated whenever app bundle is updated
|
||||||
|
new webpack.optimize.CommonsChunkPlugin({
|
||||||
|
name: 'manifest',
|
||||||
|
chunks: ['vendor'],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
@@ -1,29 +1,38 @@
|
|||||||
'use strict';
|
/* eslint-disable no-console */
|
||||||
|
const path = require('path');
|
||||||
|
const loopback = require('loopback');
|
||||||
|
const boot = require('loopback-boot');
|
||||||
|
|
||||||
var loopback = require('loopback');
|
const app = module.exports = loopback();
|
||||||
var boot = require('loopback-boot');
|
|
||||||
|
|
||||||
var app = module.exports = loopback();
|
const bootOptions = {
|
||||||
|
appRootDir: path.resolve(__dirname),
|
||||||
|
bootScripts: [
|
||||||
|
'boot/authentication.js',
|
||||||
|
'boot/webpack-dev.js',
|
||||||
|
'boot/webpack-hmr.js',
|
||||||
|
'boot/root.js',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
app.start = function() {
|
// start the webserver
|
||||||
// start the web server
|
app.start = () => app.listen(() => {
|
||||||
return app.listen(function() {
|
|
||||||
app.emit('started');
|
app.emit('started');
|
||||||
var baseUrl = app.get('url').replace(/\/$/, '');
|
|
||||||
|
const baseUrl = app.get('url').replace(/\/$/, '');
|
||||||
console.log('Web server listening at: %s', baseUrl);
|
console.log('Web server listening at: %s', baseUrl);
|
||||||
|
|
||||||
if (app.get('loopback-component-explorer')) {
|
if (app.get('loopback-component-explorer')) {
|
||||||
var explorerPath = app.get('loopback-component-explorer').mountPath;
|
const explorerPath = app.get('loopback-component-explorer').mountPath;
|
||||||
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
|
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
// Bootstrap the application, configure models, datasources and middleware.
|
// Bootstrap the application, configure models, datasources and middleware.
|
||||||
// Sub-apps like REST API are mounted via boot scripts.
|
// Sub-apps like REST API are mounted via boot scripts.
|
||||||
boot(app, __dirname, function(err) {
|
boot(app, bootOptions, (err) => {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
// start the server if `$ node server.js`
|
// start the server if `$ node server.js`
|
||||||
if (require.main === module)
|
if (require.main === module) app.start();
|
||||||
app.start();
|
|
||||||
});
|
});
|
||||||
|
|||||||
BIN
src/assets/logo.png
Normal file
BIN
src/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
13
src/index.html
Normal file
13
src/index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||||
|
<title>Vue Demo</title>
|
||||||
|
<meta name="description" content="Vue.js demo app">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
3
src/main.js
Normal file
3
src/main.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
/* eslint-env browser */
|
||||||
|
|
||||||
|
document.querySelector('#app').innerHTML = 'Hello from main.js!';
|
||||||
Reference in New Issue
Block a user