Skip to content

Commit

Permalink
webpack: add a custom webpack configuration file
Browse files Browse the repository at this point in the history
* BETTER Add the possiblity to have a custom webpack configuration
files.

Signed-off-by: Johnny Mariéthoz <[email protected]>
  • Loading branch information
jma committed Oct 3, 2019
1 parent 1ff5b6a commit 469fa83
Show file tree
Hide file tree
Showing 9 changed files with 363 additions and 2 deletions.
4 changes: 4 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,7 @@ recursive-include sonar *.woff2

include tests/ui/shibboleth_authenticator/data/valid_saml_response
recursive-include data *.crt

# added by check_manifest.py
recursive-include sonar *.babelrc
recursive-include sonar *.eslintignore
3 changes: 3 additions & 0 deletions sonar/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from invenio_oauthclient.contrib import orcid
from invenio_records_rest.facets import terms_filter
from invenio_records_rest.utils import allow_all, check_elasticsearch
from pywebpack import WebpackProject

from sonar.modules.documents.api import DocumentRecord, DocumentSearch
from sonar.modules.institutions.api import InstitutionRecord, InstitutionSearch
Expand Down Expand Up @@ -384,3 +385,5 @@ def _(x):
)
)
)

WEBPACKEXT_PROJECT = 'sonar.theme.webpack:project'
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def get_mef_person_link(id, key, value):
mef_url = None
if id:
identifier = id[1:].split(')')
url = "{mef}/?q={org}.{org}_pid:{pid}".format(
url = "{mef}/?q={org}.pid:{pid}".format(
mef="https://{host}/api/mef".format(host=DEV_HOST),
org=identifier[0].lower(),
pid=identifier[1]
Expand Down
10 changes: 9 additions & 1 deletion sonar/theme/webpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@

from __future__ import absolute_import, print_function

from flask_webpackext import WebpackBundle
from flask_webpackext import WebpackBundle, WebpackBundleProject
from pywebpack import bundles_from_entry_point

project = WebpackBundleProject(
'sonar.theme',
project_folder='webpack_assets',
config_path='build/config.json',
bundles=bundles_from_entry_point('invenio_assets.webpack'),
)

theme = WebpackBundle(
__name__,
Expand Down
6 changes: 6 additions & 0 deletions sonar/theme/webpack_assets/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
1 change: 1 addition & 0 deletions sonar/theme/webpack_assets/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/*.js
38 changes: 38 additions & 0 deletions sonar/theme/webpack_assets/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
Swiss Open Access Repository
Copyright (C) 2019 RERO
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
sourceType: 'module'
},
env: {
browser: true,
},
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
extends: 'react-app',
// add your custom rules here
'rules': {
// allow paren-less arrow functions
'arrow-parens': 0,
// allow async-await
'generator-star-spacing': 0,
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
}
}
228 changes: 228 additions & 0 deletions sonar/theme/webpack_assets/build/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
/*
Swiss Open Access Repository
Copyright (C) 2019 RERO
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

const CleanWebpackPlugin = require('clean-webpack-plugin');
const config = require('./config');
const ManifestPlugin = require('webpack-manifest-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const safePostCssParser = require('postcss-safe-parser');
const TerserPlugin = require('terser-webpack-plugin');
const webpack = require('webpack');

var webpackConfig = {
entry: config.entry,
context: config.build.context,
resolve: {
extensions: ['*', '.js', '.jsx'],
symlinks: false
},
output: {
path: config.build.assetsPath,
filename: 'js/[name].[chunkhash].js',
chunkFilename: 'js/[id].[chunkhash].js',
publicPath: config.build.assetsURL
},
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
parse: {
// we want terser to parse ecma 8 code. However, we don't want it
// to apply any minfication steps that turns valid ecma 5 code
// into invalid ecma 5 code. This is why the 'compress' and 'output'
// sections only apply transformations that are ecma 5 safe
// https://github.com/facebook/create-react-app/pull/4234
ecma: 8
},
compress: {
ecma: 5,
warnings: false,
// Disabled because of an issue with Uglify breaking seemingly valid code:
// https://github.com/facebook/create-react-app/issues/2376
// Pending further investigation:
// https://github.com/mishoo/UglifyJS2/issues/2011
comparisons: false,
// Disabled because of an issue with Terser breaking valid code:
// https://github.com/facebook/create-react-app/issues/5250
// Pending further investigation:
// https://github.com/terser-js/terser/issues/120
inline: 2
},
mangle: {
safari10: true
},
output: {
ecma: 5,
comments: false,
// Turned on because emoji and regex is not minified properly using default
// https://github.com/facebook/create-react-app/issues/2488
ascii_only: true
}
},
// Use multi-process parallel running to improve the build speed
// Default number of concurrent runs: os.cpus().length - 1
parallel: true,
cache: true
}),
new OptimizeCSSAssetsPlugin({
cssProcessorOptions: {
parser: safePostCssParser,
map: false
}
})
],
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: "vendor",
chunks: "initial",
},
},
chunks: 'all',
},
// Extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated.
runtimeChunk: {
name: 'manifest'
}
},
module: {
rules: [
{
test: require.resolve('jquery'),
use: [{
loader: 'expose-loader',
options: 'jQuery'
},{
loader: 'expose-loader',
options: '$'
}]
},
{
test: /\.(js|jsx)$/,
exclude: [/node_modules/, /@babel(?:\/|\\{1,2})runtime/],
use: [
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"],
plugins: ["@babel/plugin-proposal-class-properties", "@babel/plugin-transform-runtime"]
}
}
]
},
{
test: /\.(js|jsx)$/,
enforce: "pre",
exclude: /node_modules/,
use: [
{
options: {
emitWarning: true,
quiet: true,
formatter: require('eslint-friendly-formatter'),
eslintPath: require.resolve('eslint'),
},
loader: require.resolve('eslint-loader'),
}
]
},
{
test: /\.(scss|css)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
minimize: {
safe: true
}
}
},
{
loader: "sass-loader",
options: {}
}
]
},
// Inline images smaller than 10k
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: require.resolve('url-loader'),
options: {
limit: 10000,
name: 'img/[name].[hash:7].[ext]'
}
}
],
},
// Inline webfonts smaller than 10k
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: [
{
loader: require.resolve('file-loader'),
options: {
limit: 10000,
name: 'fonts/[name].[hash:7].[ext]'
}
}
],
}
]
},
// devtool: process.env.NODE_ENV === 'production' ? 'source-map' : 'cheap-source-map',
plugins: [
// Pragmas
new webpack.DefinePlugin({
'process.env': process.env.NODE_ENV
}),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "css/[name].[contenthash].css",
chunkFilename: "css/[name].[contenthash].css",
}),
// Removes the dist folder before each run.
new CleanWebpackPlugin(config.build.assetsPath, {allowExternal: true}),
// Automatically inject jquery
new webpack.ProvidePlugin({
jQuery: 'jquery/src/jquery',
$: 'jquery/src/jquery',
jquery: 'jquery/src/jquery',
'window.jQuery': 'jquery/src/jquery'
}),
// Write manifest file which Python will read.
new ManifestPlugin({
fileName: 'manifest.json',
stripSrc: true,
publicPath: config.build.assetsURL
})
],
performance: { hints: false }
}

if (process.env.npm_config_report) {
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig
73 changes: 73 additions & 0 deletions sonar/theme/webpack_assets/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"name": "invenio-assets",
"version": "1.0.0",
"description": "Invenio assets",
"author": "CERN <[email protected]>",
"private": true,
"scripts": {
"start": "webpack --watch --config ./build/webpack.config.js",
"build": "webpack --mode production --config ./build/webpack.config.js"
},
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.2.0",
"@babel/plugin-proposal-class-properties": "^7.2.1",
"@babel/runtime": "^7.2.0",
"@babel/preset-react": "^7.0.0",
"autoprefixer": "^6.7.2",
"babel-eslint": "^9.0.0",
"babel-loader": "^8.0.4",
"babel-register": "^6.26.0",
"chalk": "^2.4.1",
"clean-webpack-plugin": "^1.0.0",
"css-loader": "^0.26.1",
"eslint": "^5.10.0",
"eslint-config-prettier": "3.3.0",
"eslint-config-react-app": "^3.0.5",
"eslint-config-standard": "^12.0.0",
"eslint-friendly-formatter": "^4.0.1",
"eslint-loader": "^2.1.1",
"eslint-plugin-import": "2.14.0",
"eslint-plugin-jsx-a11y": "6.1.2",
"eslint-plugin-node": ">=7.0.0",
"eslint-plugin-prettier": "3.0.0",
"eslint-plugin-promise": "^4.0.1",
"eslint-plugin-react": "7.11.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-flowtype": "^2.0.0",
"eventsource-polyfill": "^0.9.6",
"expose-loader": "^0.7.5",
"file-loader": "^2.0.0",
"friendly-errors-webpack-plugin": "^1.7.0",
"function-bind": "^1.1.1",
"mini-css-extract-plugin": "0.5.0",
"node-sass": "^4.11.0",
"optimize-css-assets-webpack-plugin": "5.0.1",
"ora": "^3.0.0",
"postcss-flexbugs-fixes": "^4.1.0",
"postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.4.0",
"postcss-safe-parser": "^4.0.1",
"prettier": "1.15.3",
"rimraf": "^2.6.2",
"sass-loader": "^7.1.0",
"semver": "^5.6.0",
"style-loader": "^0.23.1",
"terser-webpack-plugin": "^1.1.0",
"url-loader": "^1.1.2",
"webpack": "^4.27.1",
"webpack-bundle-analyzer": "^3.0.3",
"webpack-cli": "^3.1.2",
"webpack-dev-middleware": "^3.4.0",
"webpack-hot-middleware": "^2.24.3",
"webpack-manifest-plugin": "2.0.4",
"webpack-merge": "^4.1.5",
"webpack-yam-plugin": "^1.0.1"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
}
}

0 comments on commit 469fa83

Please sign in to comment.