Merge pull request #494 from betagouv/legacybundle

🐎 Le build par défaut est conçu pour les navigateurs récents
pull/467/head
Johan Girod 2019-03-21 20:03:21 +01:00 committed by GitHub
commit ac1437bb49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 1061 additions and 1332 deletions

View File

@ -1,17 +1,5 @@
{
"presets": [
[
"@babel/env",
{
"targets": {
"browsers": ["last 2 versions", "safari >= 7", "ie 11"]
},
"modules": false
}
],
"@babel/react",
"@babel/flow"
],
"presets": ["@babel/react", "@babel/flow"],
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-do-expressions",

View File

@ -57,6 +57,9 @@
}
</style>
<!--<![endif]-->
<% for (var css in htmlWebpackPlugin.files.css) { %>
<link href="<%= htmlWebpackPlugin.files.css[css] %>" rel="stylesheet" />
<% } %>
<style>
html[data-useragent*='MSIE 10.0'] #outdated-browser {
display: block !important;
@ -197,7 +200,17 @@
>
</h2>
</div>
<% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
<script
type="module"
src="<%= htmlWebpackPlugin.files.chunks[chunk].entry %>"
></script>
<script nomodule src="<%= chunk %>.legacy.bundle.js"></script>
<% } %>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=all"></script>
<!-- Add polyfill.io for a very narrow web feature
IntersectionObserver : SAFARI 11 & 12.0 https://caniuse.com/#search=intersectionobserver
-->
<script src="https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
</body>
</html>

View File

@ -19,8 +19,9 @@
"not ie < 11"
],
"dependencies": {
"@babel/polyfill": "^7.4.0",
"@babel/runtime": "^7.3.4",
"@researchgate/react-intersection-observer": "^0.7.3",
"babel-regenerator-runtime": "^6.5.0",
"classnames": "^2.2.5",
"color-convert": "^1.9.2",
"focus-trap-react": "^3.1.2",
@ -56,10 +57,11 @@
"redux-form": "^7.4.2",
"redux-thunk": "^2.3.0",
"reselect": "^4.0.0",
"screenfull": "^3.3.2"
"screenfull": "^3.3.2",
"whatwg-fetch": "^3.0.0"
},
"scripts": {
"compile": "webpack --config source/webpack.prod.js",
"compile": "yarn run webpack --config source/webpack.prod.js && yarn run webpack --config source/webpack.prod.legacyBrowser.js",
"stats": "webpack --config source/webpack.prod.js --profile --json > stats.json",
"eslint-check": "eslint --print-config .eslintrc | eslint-config-prettier-check",
"eslint": "LIST=`git diff --cached --name-only --diff-filter=AMR HEAD | grep .*\\.js | grep -v json`; if [ \"$LIST\" ]; then eslint $LIST; fi",
@ -94,8 +96,7 @@
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/polyfill": "^7.0.0",
"@babel/preset-env": "^7.1.0",
"@babel/preset-env": "^7.3.4",
"@babel/preset-flow": "^7.0.0-beta.51",
"@babel/preset-react": "^7.0.0",
"akh": "^3.1.2",
@ -103,7 +104,6 @@
"babel-eslint": "^11.0.0-beta.0",
"babel-loader": "^8.0.2",
"babel-plugin-ramda": "^1.6.3",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-webpack-alias": "^2.1.2",
"chai": "^4.1.2",
"co-request": "^1.0.0",
@ -155,7 +155,6 @@
"webpack-cli": "^3.1.2",
"webpack-dev-middleware": "^3.4.0",
"webpack-hot-middleware": "^2.24.2",
"webpack-pwa-manifest": "^3.6.2",
"workbox-webpack-plugin": "^3.6.1",
"yaml-loader": "^0.5.0"
},

View File

@ -60,6 +60,19 @@ export default class Provider extends PureComponent {
storeEnhancer
)
this.props.onStoreCreated && this.props.onStoreCreated(this.store)
// Remove loader
var css = document.createElement('style')
css.type = 'text/css'
css.innerHTML = `
#js {
opacity: 1 !important;
transform: translateY(0px) !important;
}
#lds-ellipsis {
display: none !important;
}`
document.body.appendChild(css)
}
render() {
return (

View File

@ -1,20 +1,28 @@
import { goBackToSimulation } from 'Actions/actions';
import { ScrollToTop } from 'Components/utils/Scroll';
import { encodeRuleName } from 'Engine/rules';
import { decodeRuleName, findRuleByDottedName, findRulesByName } from 'Engine/rules.js';
import { compose, head, path } from 'ramda';
import React, { Component } from 'react';
import emoji from 'react-easy-emoji';
import { Trans, withTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import { Link, Redirect } from 'react-router-dom';
import { flatRulesSelector, noUserInputSelector, situationBranchNameSelector } from 'Selectors/analyseSelectors';
import { capitalise0 } from "../utils";
import Namespace from './rule/Namespace';
import Rule from './rule/Rule';
import './RulePage.css';
import SearchButton from './SearchButton';
import { goBackToSimulation } from 'Actions/actions'
import { ScrollToTop } from 'Components/utils/Scroll'
import { encodeRuleName } from 'Engine/rules'
import {
decodeRuleName,
findRuleByDottedName,
findRulesByName
} from 'Engine/rules.js'
import { compose, head, path } from 'ramda'
import React, { Component } from 'react'
import emoji from 'react-easy-emoji'
import { Trans, withTranslation } from 'react-i18next'
import { connect } from 'react-redux'
import { withRouter } from 'react-router'
import { Link, Redirect } from 'react-router-dom'
import {
flatRulesSelector,
noUserInputSelector,
situationBranchNameSelector
} from 'Selectors/analyseSelectors'
import { capitalise0 } from '../utils'
import Namespace from './rule/Namespace'
import Rule from './rule/Rule'
import './RulePage.css'
import SearchButton from './SearchButton'
export default compose(
connect(state => ({
@ -43,7 +51,13 @@ export default compose(
if (rules.find(({ ns }) => ns == null))
return this.renderRule(decodedRuleName)
if (rules.length > 1)
return <DisambiguateRuleQuery rules={rules} flatRules={flatRules} name={name}/>
return (
<DisambiguateRuleQuery
rules={rules}
flatRules={flatRules}
name={name}
/>
)
let dottedName = head(rules).dottedName
return this.renderRule(dottedName)
}
@ -77,9 +91,10 @@ const BackToSimulation = compose(
render() {
let { goBackToSimulation } = this.props
return (
<button className="ui__ link-button" onClick={goBackToSimulation}>
{emoji('⬅️')}
<Trans i18nKey="back">Reprendre la simulation</Trans>
<button
className="ui__ simple small button"
onClick={goBackToSimulation}>
{emoji('⬅️')} <Trans i18nKey="back">Reprendre la simulation</Trans>
</button>
)
}

View File

@ -49,10 +49,9 @@ export default compose(
</Overlay>
) : (
<button
className="ui__ link-button"
className="ui__ simple small button"
onClick={() => this.setState({ visible: true })}>
{emoji('🔍')}
<Trans>Rechercher</Trans>
{emoji('🔍')} <Trans>Rechercher</Trans>
</button>
)
}

View File

@ -1,4 +1,3 @@
import { T } from 'Components'
import React, { useState } from 'react'
import emoji from 'react-easy-emoji'

View File

@ -53,11 +53,16 @@ export default compose(
{this.state.displayAnswers && (
<Answers onClose={() => this.setState({ displayAnswers: false })} />
)}
<div style={{ display: 'flex', justifyContent: 'center' }}>
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'baseline'
}}>
{arePreviousAnswers ? (
<button
style={{ marginRight: '1em' }}
className="ui__ small button "
className="ui__ small button "
onClick={() => this.setState({ displayAnswers: true })}>
<T>Voir mes réponses</T>
</button>

View File

@ -73,11 +73,3 @@ span.ui__.enumeration:not(:last-of-type)::after {
margin: 0 0.3rem;
display: inline-block;
}
#js {
opacity: 1;
transform: translateY(0px);
}
#lds-ellipsis {
display: none;
}

View File

@ -1,61 +1,20 @@
import React from 'react'
import { Parser } from 'nearley'
import Grammar from './grammar.ne'
import {
contains,
propEq,
curry,
cond,
equals,
divide,
multiply,
map,
intersection,
keys,
propOr,
always,
head,
gte,
lte,
lt,
gt,
add,
subtract
} from 'ramda'
import { evaluateNode, rewriteNode, makeJsx, mergeMissing } from './evaluation'
import { Node } from './mecanismViews/common'
import {
treatVariable,
treatNegatedVariable,
treatVariableTransforms
} from './treatVariable'
import { treat } from './traverse'
import knownMecanisms from './known-mecanisms.yaml'
// This should be the new way to implement mecanisms
// In a specific file
// TODO import them automatically
// TODO convert the legacy functions to new files
import barème from 'Engine/mecanisms/barème.js'
import barème from 'Engine/mecanisms/barème.js';
import { Parser } from 'nearley';
import { add, always, cond, contains, curry, divide, equals, gt, gte, head, intersection, keys, lt, lte, map, multiply, propEq, propOr, subtract } from 'ramda';
import React from 'react';
import { evaluateNode, makeJsx, mergeMissing, rewriteNode } from './evaluation';
import Grammar from './grammar.ne';
import knownMecanisms from './known-mecanisms.yaml';
import { mecanismAllOf, mecanismComplement, mecanismContinuousScale, mecanismError, mecanismInversion, mecanismLinearScale, mecanismMax, mecanismMin, mecanismNumericalSwitch, mecanismOneOf, mecanismProduct, mecanismReduction, mecanismSelection, mecanismSum, mecanismSynchronisation, mecanismVariations } from './mecanisms';
import { Node } from './mecanismViews/common';
import { treat } from './traverse';
import { treatNegatedVariable, treatVariable, treatVariableTransforms } from './treatVariable';
import {
mecanismOneOf,
mecanismAllOf,
mecanismNumericalSwitch,
mecanismSum,
mecanismProduct,
mecanismLinearScale,
mecanismContinuousScale,
mecanismMax,
mecanismMin,
mecanismError,
mecanismComplement,
mecanismSelection,
mecanismInversion,
mecanismReduction,
mecanismVariations,
mecanismSynchronisation
} from './mecanisms'
let nearley = () => new Parser(Grammar.ParserRules, Grammar.ParserStart)
export let treatString = (rules, rule) => rawNode => {

View File

@ -596,3 +596,5 @@ newsletter:
description2: 'Register to our <1>monthly newsletter</1> by leaving your email:'
S'inscrire: Register
simulationWarning: This is an estimate based on <2>purely theoretical data</2> on turnover, charges and the single tax base without children, excluding any other income, which <5>cannot be the responsibility of the social security bodies concerned with regard to the actual declarations and calculations.</5>
Renseigner mon entreprise: Find my company
Simulations personnalisées: Customized simulations

View File

@ -1,3 +1,4 @@
import '@babel/polyfill'
import 'iframe-resizer'
import React from 'react'
import { render } from 'react-dom'

View File

@ -1,3 +1,4 @@
import Route404 from 'Components/Route404'
import RulePage from 'Components/RulePage'
import TrackPageView from 'Components/utils/TrackPageView'
import withSitePaths from 'Components/utils/withSitePaths'
@ -6,7 +7,7 @@ import { compose } from 'ramda'
import createRavenMiddleware from 'raven-for-redux'
import Raven from 'raven-js'
import React, { Component } from 'react'
import {Helmet} from 'react-helmet'
import { Helmet } from 'react-helmet'
import { withTranslation } from 'react-i18next'
import { Route, Switch } from 'react-router-dom'
import 'Ui/index.css'
@ -24,7 +25,6 @@ import Landing from './pages/Landing'
import Sitemap from './pages/Sitemap'
import SocialSecurity from './pages/SocialSecurity'
import { constructLocalizedSitePath } from './sitePaths'
import Route404 from 'Components/Route404'
if (process.env.NODE_ENV === 'production') {
Raven.config(

View File

@ -1,3 +1,4 @@
import '@babel/polyfill'
import React from 'react'
import { render } from 'react-dom'
import App from './App'

View File

@ -1,7 +1,7 @@
import '@babel/polyfill'
import React from 'react'
import { render } from 'react-dom'
import App from './App'
let anchor = document.querySelector('#js')
render(<App language="fr" basename="mon-entreprise" />, anchor)

View File

@ -1,18 +1,18 @@
/* @flow */
import { Component, React, T } from 'Components';
import { ScrollToTop } from 'Components/utils/Scroll';
import withLanguage from 'Components/utils/withLanguage';
import withSitePaths from 'Components/utils/withSitePaths';
import { compose } from 'ramda';
import emoji from 'react-easy-emoji';
import {Helmet} from 'react-helmet';
import { withTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { régimeSelector } from 'Selectors/companyStatusSelectors';
import * as Animate from 'Ui/animate';
import Video from './Video';
import { Component, React, T } from 'Components'
import { ScrollToTop } from 'Components/utils/Scroll'
import withLanguage from 'Components/utils/withLanguage'
import withSitePaths from 'Components/utils/withSitePaths'
import { compose } from 'ramda'
import emoji from 'react-easy-emoji'
import { Helmet } from 'react-helmet'
import { withTranslation } from 'react-i18next'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import { régimeSelector } from 'Selectors/companyStatusSelectors'
import * as Animate from 'Ui/animate'
import Video from './Video'
import type { Match, Location } from 'react-router'
import type { TFunction } from 'react-i18next'
@ -50,29 +50,32 @@ class SocialSecurity extends Component<Props, {}> {
<strong>bien-être général de la population</strong>.
</p>
</T>
{showFindYourCompanyLink && (<>
<h2>Simulations personnalisées</h2>
<p>
<T k="sécu.entrepriseCrée">
Si vous possédez déjà une entreprise, nous pouvons{' '}
<strong>automatiquement personnaliser</strong> vos simulations
à votre situation.
</T>
</p>
<div style={{textAlign: 'center'}}>
<Link to={sitePaths.entreprise.trouver} className="ui__ button">
Renseigner mon entreprise
{showFindYourCompanyLink && (
<>
<h2>
<T>Simulations personnalisées</T>
</h2>
<p>
<T k="sécu.entrepriseCrée">
Si vous possédez déjà une entreprise, nous pouvons{' '}
<strong>automatiquement personnaliser</strong> vos
simulations à votre situation.
</T>
</p>
<div style={{ textAlign: 'center' }}>
<Link
to={sitePaths.entreprise.trouver}
className="ui__ button plain">
<T>Renseigner mon entreprise</T>
</Link>
</div>
</div>
</>
)}
{!['mycompanyinfrance.fr', 'mon-entreprise.fr'].includes(
window.location.hostname
) ? (
<>
<h2 >
Que souhaitez-vous estimer ?
</h2>
<h2>Que souhaitez-vous estimer ?</h2>
<Link
className="landing__choice "
to={

View File

@ -3,9 +3,9 @@ const HTMLPlugin = require('html-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin')
const { EnvironmentPlugin } = require('webpack')
const path = require('path')
const { universal, web } = require('./webpack.commonLoaders.js')
module.exports = {
resolve: {
alias: {
Engine: path.resolve('source/engine/'),
@ -20,18 +20,15 @@ module.exports = {
}
},
entry: {
embauche: ['./source/sites/embauche.gouv.fr/entry.js'],
'mon-entreprise': ['babel-regenerator-runtime', './source/sites/mycompanyinfrance.fr/entry.fr.js'],
infrance: ['babel-regenerator-runtime', './source/sites/mycompanyinfrance.fr/entry.en.js'],
embauche: './source/sites/embauche.gouv.fr/entry.js',
'mon-entreprise': './source/sites/mycompanyinfrance.fr/entry.fr.js',
infrance: './source/sites/mycompanyinfrance.fr/entry.en.js',
// To not introduce breaking into the iframe integration, we serve simulateur.js from a 'dist' subdirectory
'dist/simulateur': ['./source/sites/embauche.gouv.fr/iframe-script.js'],
'dist/simulateur': './source/sites/embauche.gouv.fr/iframe-script.js',
},
output: {
path: path.resolve('./dist/')
},
module: {
rules: [...web, ...universal]
path: path.resolve('./dist/'),
},
plugins: [
new EnvironmentPlugin({
@ -40,6 +37,7 @@ module.exports = {
}),
new HTMLPlugin({
template: 'index.html',
inject: false,
chunks: ['infrance'],
title:
'My company in France: A step-by-step guide to start a business in France',
@ -49,6 +47,7 @@ module.exports = {
}),
new HTMLPlugin({
template: 'index.html',
inject: false,
chunks: ['embauche'],
title: "Simulateur d'embauche 🤝",
description:
@ -57,6 +56,7 @@ module.exports = {
}),
new HTMLPlugin({
template: 'index.html',
inject: false,
chunks: ['mon-entreprise'],
title:
"Mon-entreprise.fr : Le guide officiel du créateur d'entreprise",

View File

@ -1,23 +1,45 @@
module.exports = {
web: [
module.exports.styleLoader = styleLoader => ({
test: /\.css$/,
use: [
{ loader: styleLoader },
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
sourceMap: true,
importLoaders: 1
loader: 'css-loader',
options: {
sourceMap: true,
importLoaders: 1
}
},
{
loader: 'postcss-loader'
}
]
})
module.exports.commonLoaders = ({ legacy = false } = {}) => {
const babelLoader = {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
targets: !legacy
? {
esmodules: true
}
: {
esmodules: false,
browsers: ['ie 11']
},
useBuiltIns: 'entry'
}
},
{
loader: 'postcss-loader'
}
]
]
}
],
universal: [
}
return [
{ test: /\.js$/, loader: babelLoader, exclude: /node_modules|dist/ },
{
test: /\.(jpe?g|png|svg)$/,
use: {
@ -29,16 +51,12 @@ module.exports = {
},
{
test: /\.yaml$/,
loader: 'json-loader!yaml-loader'
},
{
test: /\.js$/,
exclude: /node_modules|dist/,
loader: 'babel-loader'
use: ['json-loader', 'yaml-loader']
},
{
test: /\.ne$/,
loader: 'babel-loader!nearley-loader'
use: [babelLoader, 'nearley-loader']
}
]
}

View File

@ -1,11 +1,15 @@
const { map, concat } = require('ramda')
const { map } = require('ramda')
const webpack = require('webpack')
const common = require('./webpack.common.js')
const { commonLoaders, styleLoader } = require('./webpack.commonLoaders')
module.exports = {
...common,
module: {
rules: [...commonLoaders(), styleLoader('style-loader')]
},
mode: 'development',
entry: map(concat(['webpack-hot-middleware/client']), common.entry),
entry: map(entry => ['webpack-hot-middleware/client', entry], common.entry),
plugins: [
...common.plugins,
new webpack.EnvironmentPlugin({ NODE_ENV: 'development' }),

View File

@ -1,6 +1,6 @@
const common = require('./webpack.common.js')
const { universal } = require('./webpack.commonLoaders.js')
const path = require('path')
const { commonLoaders, styleLoader } = require('./webpack.commonLoaders')
module.exports = {
resolve: common.resolve,
@ -15,24 +15,6 @@ module.exports = {
globalObject: "(typeof window !== 'undefined' ? window : this)"
},
module: {
rules: [
...universal,
{
test: /\.css$/,
use: [
'isomorphic-style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true,
importLoaders: 1
}
},
{
loader: 'postcss-loader'
}
]
}
]
rules: [...commonLoaders(), styleLoader('isomorphic-style-loader')]
}
}

View File

@ -1,10 +1,12 @@
const common = require('./webpack.common.js')
const WorkboxPlugin = require('workbox-webpack-plugin')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const WorkboxPlugin = require('workbox-webpack-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
const path = require('path')
const cheerio = require('cheerio')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const { commonLoaders, styleLoader } = require('./webpack.commonLoaders')
const prerenderConfig = () => ({
staticDir: path.resolve('dist'),
@ -32,27 +34,28 @@ const prerenderConfig = () => ({
`)
// Remove piwik script
$('script[src$="stats.data.gouv.fr/piwik.js"]').remove()
context.html = $.html()
return context
}
})
// Replace style-loader with MiniCssExtractPlugin.loader
common.module.rules
.find(rule => rule.test.test('a.css'))
.use.find(loader => loader.loader === 'style-loader').loader =
MiniCssExtractPlugin.loader
module.exports = {
...common,
module: {
rules: [...commonLoaders(), styleLoader(MiniCssExtractPlugin.loader)]
},
output: {
...common.output,
filename: ({ chunk }) => {
return chunk.name === 'dist/simulateur'
? '[name].js'
: '[name].[contenthash].bundle.js'
}
},
mode: 'production',
devtool: 'source-map',
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].[hash].css',
chunkFilename: '[id].[hash].css'
}),
...common.plugins,
new WorkboxPlugin.GenerateSW({
clientsClaim: true,
@ -61,7 +64,7 @@ module.exports = {
runtimeCaching: [
{
urlPattern: new RegExp(
'https://fonts.(?:googleapis|gstatic).com/(.*)|https://cdn.polyfill.io/v2/polyfill.min.js'
'https://fonts.(?:googleapis|gstatic).com/(.*)'
),
handler: 'cacheFirst',
options: {
@ -85,6 +88,12 @@ module.exports = {
/^\/sitemap\.infrance\.en\.txt$/
]
}),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].[hash].css',
chunkFilename: '[id].[hash].css'
}),
new PrerenderSPAPlugin({
...prerenderConfig(),
outputDir: path.resolve('dist', 'prerender', 'infrance'),

View File

@ -0,0 +1,21 @@
const { map } = require('ramda')
const prod = require('./webpack.prod.js')
const { commonLoaders, styleLoader } = require('./webpack.commonLoaders')
const { EnvironmentPlugin } = require('webpack')
module.exports = {
...prod,
entry: map(entry => ['whatwg-fetch', entry], prod.entry),
output: {
filename: '[name].legacy.bundle.js'
},
module: {
rules: [...commonLoaders({ legacy: true }), styleLoader('style-loader')]
},
plugins: [
new EnvironmentPlugin({
EN_SITE: '/infrance${path}',
FR_SITE: '/mon-entreprise${path}'
})
]
}

View File

@ -1,8 +1,12 @@
var webpack = require('webpack'),
common = require('./webpack.common.js')
common = require('./webpack.common.js'),
{ commonLoaders, styleLoader } = require('./webpack.commonLoaders')
module.exports = {
...common,
module: {
rules: [...commonLoaders(), styleLoader('style-loader')]
},
mode: 'development',
plugins: [new webpack.EnvironmentPlugin({ NODE_ENV: 'development' })]
}

1948
yarn.lock

File diff suppressed because it is too large Load Diff