setup webpack
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,6 +14,7 @@
|
||||
.idea
|
||||
.project
|
||||
.strong-pm
|
||||
client
|
||||
coverage
|
||||
node_modules
|
||||
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",
|
||||
"scripts": {
|
||||
"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": {
|
||||
"babel-core": "^6.22.1",
|
||||
"babel-loader": "^6.2.10",
|
||||
"babel-preset-es2015": "^6.22.0",
|
||||
"compression": "^1.0.3",
|
||||
"cors": "^2.5.2",
|
||||
"favicons-webpack-plugin": "^0.0.7",
|
||||
"file-loader": "^0.9.0",
|
||||
"helmet": "^1.3.0",
|
||||
"html-webpack-plugin": "^2.26.0",
|
||||
"json-loader": "^0.5.4",
|
||||
"loopback": "^3.0.0",
|
||||
"loopback-boot": "^2.6.5",
|
||||
"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": {
|
||||
"eslint": "^3.13.0",
|
||||
"eslint-config-airbnb": "^14.0.0",
|
||||
"eslint-plugin-import": "^2.2.0",
|
||||
"eslint-plugin-jsx-a11y": "^3.0.2",
|
||||
"eslint-plugin-react": "^6.9.0",
|
||||
"eslint-config-airbnb": "^14.0.0",
|
||||
"nsp": "^2.1.0"
|
||||
"nodemon": "^1.11.0",
|
||||
"nsp": "^2.1.0",
|
||||
"rimraf": "^2.5.4"
|
||||
},
|
||||
"repository": {
|
||||
"type": "",
|
||||
"url": ""
|
||||
},
|
||||
"license": "UNLICENSED",
|
||||
"license": "MIT",
|
||||
"description": "02-customer-portal"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function enableAuthentication(server) {
|
||||
// enable authentication
|
||||
// server.enableAuth();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const pingRoute = require('./routes/ping');
|
||||
|
||||
module.exports = function(server) {
|
||||
var router = server.loopback.Router();
|
||||
module.exports = (server) => {
|
||||
const router = server.loopback.Router();
|
||||
|
||||
// Install a `/` route that returns server 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');
|
||||
var boot = require('loopback-boot');
|
||||
const app = module.exports = loopback();
|
||||
|
||||
var app = module.exports = loopback();
|
||||
|
||||
app.start = function() {
|
||||
// start the web server
|
||||
return app.listen(function() {
|
||||
app.emit('started');
|
||||
var baseUrl = app.get('url').replace(/\/$/, '');
|
||||
console.log('Web server listening at: %s', baseUrl);
|
||||
if (app.get('loopback-component-explorer')) {
|
||||
var explorerPath = app.get('loopback-component-explorer').mountPath;
|
||||
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
|
||||
}
|
||||
});
|
||||
const bootOptions = {
|
||||
appRootDir: path.resolve(__dirname),
|
||||
bootScripts: [
|
||||
'boot/authentication.js',
|
||||
'boot/webpack-dev.js',
|
||||
'boot/webpack-hmr.js',
|
||||
'boot/root.js',
|
||||
],
|
||||
};
|
||||
|
||||
// start the webserver
|
||||
app.start = () => app.listen(() => {
|
||||
app.emit('started');
|
||||
|
||||
const baseUrl = app.get('url').replace(/\/$/, '');
|
||||
console.log('Web server listening at: %s', baseUrl);
|
||||
|
||||
if (app.get('loopback-component-explorer')) {
|
||||
const explorerPath = app.get('loopback-component-explorer').mountPath;
|
||||
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
|
||||
}
|
||||
});
|
||||
|
||||
// Bootstrap the application, configure models, datasources and middleware.
|
||||
// Sub-apps like REST API are mounted via boot scripts.
|
||||
boot(app, __dirname, function(err) {
|
||||
boot(app, bootOptions, (err) => {
|
||||
if (err) throw err;
|
||||
|
||||
// start the server if `$ node server.js`
|
||||
if (require.main === module)
|
||||
app.start();
|
||||
if (require.main === module) 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