xing / hops Goto Github PK
View Code? Open in Web Editor NEWUniversal Development Environment
License: MIT License
Universal Development Environment
License: MIT License
On IE11 we had an "Object.assign is undefined" error. It looks like polyfills are not included in Hops. Is that an intended behavior?
In order to make it work we had to add this to our project:
import 'core-js/es6/promise';
import 'core-js/es6/object';
The current hops-template-react
template contains a lot more than just react and redux.
We should remove graphql from the hops-template-react
and create a new template hops-template-graphql
that only contains react and graphql.
Question: Do we want the new template hops-template-graphql
to contain:
Split up hops-template-react
into multiple templates.
I've been experimenting with the typecheck babel plugin for the flow syntax
and I've ran into this issue, which seems big and it's unclear if it will be fixed
at all.
codemix/babel-plugin-typecheck#134
Maybe we should consider not using typecheck and instead just provide
babel-plugin-syntax-flow
and babel-plugin-transform-flow-strip-types
?
In the past I used apollo client without hops-graphql
and just with the basic apollo features and everything worked great.
Now I try to migrate to hops-graphql
and suddenly my ssr does not work anymore because values in react context are missing.
It seems as if the rendering routine in getDataFromTree
does not work well with React.cloneElement
and/or Reacts context API.
I disabled ssr mode and tried to find the root cause for this but failed and will now give up after two hours.
I also failed to isolate the problem in a reproducible state.
In our use-case we do not need graphql queries to be run on the server since the data is highly user-specific and we use static pre-build-ssr and not dynamic ssr.
Therefore I propose to add an option to disable the ssr pre-fetching.
It might be a good idea to provide an annotated source in the example
app, instead of it being plain. Eg. comment what the decorator does,
getSelector
, createReducer
, etc...
Along with maybe a list of useful resources that might explain more in-depth
the tools and libraries this bundle includes.
Thoughts?
Some projects have written their own TypeScript typings for Hops, but keep them in their respective repositories.
Publish TypeScript typings together with Hops (as described in: https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html)
We could use these typing as a starting point: https://github.com/foosbyte/kicker-trainer/tree/hops/typings
We currently do not have a hops template featuring a GraphQL example.
We should build and provide such a template.
Before Hops V 7, there was a clear order for the calls of lifecycle methods. The async bootstrap
had been called and finished before enhanceElement
. This is currently used to fetch async data before rendering to the DOM, so Hops 7 it breaks in current applications.
Three scenarios should be supported:
Possible solution:
Turn enhanceElement
into a Promise, that receives a Promise from the chain before and returns again a Promise. This Promise should in any case resolve to a renderable Element.
Example (no runnable code, just to explain the principle):
// using jsx for clarification, should be es5
enhanceElement: function (prev) {
let data = {};
return fetchSth()
.then(remoteData => data = remoteData)
.then(prev)
.then(el => <MyProvider data={data}>{el}</MyProvider>)
.then(el => {
return doSthAsync()
.then(Promise.resolve(el));
});
}
Due to the narrow use-case of hops-transpiler
, it does not make much sense to keep it as a standalone package. It is coupled rather tightly to hops-middleware
.
Integrate hops-transpiler
into hops-middleware
and (soft-)deprecate it as a standalone package,
Is Hops supposed to work with code splitting? I'm getting this error when trying:
94% asset optimization[HOPS PLUGIN ERROR]: { Error: Cannot find module './chunk-0.js'
at Function.Module._resolveFilename (module.js:470:15)
at Function.Module._load (module.js:418:25)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
at Function.requireEnsure [as e] (/Users/drix/dev/projects/playground/hops-code-splitting/dist/bundle.js:41:25)
at Object.getIndexRoute (/Users/drix/dev/projects/playground/hops-code-splitting/dist/bundle.js:180:25)
at getIndexRoute (/Users/drix/dev/projects/playground/hops-code-splitting/node_modules/react-router/lib/matchRoutes.js:68:35)
at /Users/drix/dev/projects/playground/hops-code-splitting/node_modules/react-router/lib/matchRoutes.js:153:9
at matchRouteDeep (/Users/drix/dev/projects/playground/hops-code-splitting/node_modules/react-router/lib/matchRoutes.js:176:8)
at /Users/drix/dev/projects/playground/hops-code-splitting/node_modules/react-router/lib/matchRoutes.js:244:5 code: 'MODULE_NOT_FOUND' }
Hash: 4a0f11896f9ba5447933
I'm maybe doing things wrong with Webpack2... Here is a repo you can clone to reproduce the issue: https://github.com/drixsonic/hops-code-splitting
Currently, everything in Hops is written in ES5 (a.k.a. classical JavaScript). This means, the code in question is not as legible and concise as it could be.
As Hops itself provides a trivial way to transpile runtime code, we can and should start with hops-react, hops-redux and hops-graphql.
I find myself creating a longer and longer regex if I want to import ES6
modules. Maybe we could add an option like babelES6
which should
contain an array of folder not to be ignored by babel?
I find that babelIgnore
containing also the part of the regex that
decides which ones NOT to ignore is sort of confusing. Here's what
I'm proposing:
// lib/config.js
module.exports = overrideConfig({
// ...
babelIgnore: /node_modules\//,
babelInclude: ['es-']
// ...
})
// webpack.base.js
// ...
{
test: /\.js$/,
loader: 'babel',
exclude: new RegExp(`${config.babelIgnore}${config.babelInclude.map((i) => `(?!${i})`).join('')}`)
}
// ...
Given:
command line call
> npm test --coverage
package.json
"scripts": {
"test": "hops test"
}
Result:
Test runs with coverage, but doesn't recognize test files and source files for analysis.
Expected:
Test detects all js files in the projects and can calculate the test coverage from the defined unit tests.
We currently have two cli packages - that is (at least) one too many. Additionally, both packages expose a hops
executable - while the legacy hops
npm package is deprecated.
We ought to consolidate local and global CLI packages in a single package that should be published as hops
, reviving that package name. The existing CLI packages will be deprecated.
We have a bit of package creep. middleware
and renderer
are highly advanced packages that are seldom used on their own.
It appears we can safely deprecate them and move their contents to the build
package. This package might in turn export them.
When running tests (npm test) in a project without any tests yet, we receive linting errors about temp files, but no linting errors about our own files.
/path/to/client/.tmp/mocha-webpack/917d4d4eeb2f8fd0100e585ed757ded9-entry.js
2:40 warning Strings must use singlequote quotes
7:1 error Trailing spaces not allowed no-trailing-spaces
7:2 error Newline required at end of file but not found eol-last
hops init
creates templates without a .gitignore
file, which means that users who use it, need to create the .gitignore
files themselves.
This is caused by npm, because a .gitignore
files is never published (npm/npm#1862)
We could rename the .gitignore
file in the current hops-*
templates to _gitignore
and rename them again after unzipping the package.
Due to a vulnerability found in one of its dependencies, we'll have to upgrade node-mocks-http
as soon as this PR is merged and a new release (<1.6.5) is available.
Warning about deprecated router method (seems to be deprecated since 2.x)
Warning: [react-router] `context.location` is deprecated, please use a route component's `props.location` instead. http://tiny.cc/router-accessinglocation
https://github.com/ReactTraining/react-router/blob/master/upgrade-guides/v2.0.0.md
i installed bulma then i import in app js
but im getting an error...
node_modules/bulma/bulma.sass:1
(function (exports, require, module, __filename, __dirname) { @charset "utf-8"
Currently, the CSS output for production builds is the same as for development environments (see https://github.com/xing/hops/blob/master/packages/build-config/sections/module-rules/postcss.js#L10 )
var cssLoaderOptions = {
importLoaders: 1,
modules: true,
localIdentName: '[folder]-[name]-[local]-[hash:8]',
sourceMap: false,
};
Which results in quite long classnames. I'd like to obfuscate these way more to reduce the amount of characters shipped to users by ~70%
(rather wild guess, but folder
, name
and local
should have around 6-8 characters like the hash in the end)
Provide another set of cssLoaderOptions
for the production build with a different localIdentName
, e.g. [hash:base64:8]
.
I know this makes debugging in production a bit harder since the classnames are not that obvious. But I still think it's worth it shaving off quite some output :)
I'm trying to use the serve configuration with hops 2.1.0. When I update a file, it tries to recompile but I get the following error:
Syntax error: Unexpected token <
It seems that the hot-update.json file contains the template again. I was able to fix it by adding the following to the etc/webpack.serve.js
file provided by Hops:
output: {
publicPath: 'http://localhost:8080/'
},
worth noting that I had a similar problem with hops 1.0.0, and was able to fix in a similar way
In the server.js:
https://github.com/xing/hops/blob/v7.4.0/packages/build/server.js#L22
currently, after the devServer config options there is an additional object (the one with the after function and the watchOptions). This way, it is impossible to override that functionality. For example, you are always stuck with the rewrite:
https://github.com/xing/hops/blob/v7.4.0/packages/build/server.js#L24
even if you don't want to use that.
I would like to propose to simply change the order here:
https://github.com/xing/hops/blob/v7.4.0/packages/build/server.js#L22
from:
Object.assign({}, config.devServer, { after: .... })
to:
Object.assign({}, { after: .... }, config.devServer)
It wouldn't affect existing setups (nobody currently could have provided his/her own after: function, it would have been overridden)
(cc: @mjacobus)
The entire aws config can be found in the main.js because it is part of hops-config which gets inlined into the bundle.
This includes possibly confidential data such as certificateArn or information about the projects folder structure.
If it is agreed upon that this rather suboptimal, we could allow to blacklist keys in hops-config that will not be part of the client bundle. aws
could be one of the defaults.
One might want to use redux-saga
instead of redux-thunk
(for example),
would it be out of the scope of this project to allow for a custom store
enhancer?
Currently, hops-local-cli
contains all supported commands (except init
). It can only be extended by updating its source. We already have a couple of use cases (e.g. optional build/serve commands) in which it could seem desirable to have a more flexible, dynamic solution.
Move existing commands to the appropriate packages (e.g. hops-express
, hops-build
) and expose them as executables of those packages. Have these executables named hops-<COMMAND>
, e.g. hops-build
, hops-develop
in node_modules/.bin
and make them work in standalone-mode, as well.
module.exports = function command (callback) {
return {
/* ... */
};
};
if (require.main === module) {
// load hops local cli if called directly
var cli = require('hops-local-cli');
// access exported command definition
var def = module.exports();
// use definition to register command in hops-local-cli
cli.args.command(def);
// append defined command to have it executed
cli.run([def.command].concat(process.argv.slice(2)));
}
Adapt hops-local-cli
to scan node_modules/.bin
to dynamically find and register hops-*
commands. Add args
to hops-local-cli
's exports.
A deprecation notice shows on installation.
hops@next
hops init
that when executedhops init
- create a new project or add hops to an existing project
hops build
- creates the JS browser bundles and/or app shellshops develop
- runs a local webpack dev serverhops serve
- starts an express server (to be used in production)rewritePath
/ registerMiddleware
and other shared functionalityapp
(which can be used for aws-serverless-express)fully functional demo/example projects that can be used to init a new project
A typical hops project would therefore have the following dependencies:
hops-react
hops-redux
hops-common
(4.)hops-build
(3.) - (as a dev dependency) contains webpack config / dev serverhops-server
(2.) - (if needed) contains node serverreact(-dom|helmet|redux|router|router-dom)
, redux(-thunk)
Loading data when starting the application on the server side is a very common requirement. Often that data is needed to reasonably render an application in the first place. Hops already has the context lifecycle method bootstrap, which is too general however.
As Hops follows mainstream patterns, what you rather want to do is pass in a configuration for the redux extension that takes pairs of router paths and a list of of actions to perform before that both can be rendered. This approach is matches the best practice in router v4.
lib/exports.js
appears to be missing in the latest hops release, albeit it being in the git repo. This causes errors when trying to require hops
Given I have a Form
When the user enters data in the form
And navigates away without saving
Then I want to display a warning "Do you really want to discard..."
BUT I can not do this since the implementation of the BrowserRouter does not allow me to set a custom getUserConfirmation
hops-react should provide a way for me as a consumer to provide navigation guards.
Since I'm still not familiar with the intend/concept of the context api I find it hard to propose how to do that exactly.
Current situation:
Safari/iOS error after npm run build
Current findings:
index.html
outputs after using a "custom" buildConfig with the same build options in plugins (using the babel-minify-webpack-plugin) section:new BabelMinifyPlugin(
{ evaluate: false, mangle: false, propertyLiterals: false },
{ comments: false }
)
npm run build
output:
hops624-index-html.txt
custombuildrc-index-html.txt
custom build config:
const baseBuildConfig = Object.assign({}, require('hops-config/configs/build'));
const BabelMinifyPlugin = require('babel-minify-webpack-plugin');
baseBuildConfig.plugins = baseBuildConfig.plugins
.filter(x => x.constructor.name !== 'BabelMinifyPlugin')
.concat([
new BabelMinifyPlugin(
{ evaluate: false, mangle: false, propertyLiterals: false },
{ comments: false }
)
])
module.exports = baseBuildConfig;
There should be tests making sure those use cases all work properly
export default render(<App/>, {
extensions: [reduxExtension({reducers})],
});
export default render(
<App/>,
createContext({reducers})
);
export default render(
<App/>,
createContext({redux: {reducers}})
);
export default render(
<App/>,
createContext()
);
Fresh clone of hops.
Steps:
Env:
node v8.1.3
npm v5.3.0
Result:
> [email protected] start /Users/norbert.pabian/development/hops/demo
> hops start
hops server listening at http://0.0.0.0:8080
ERROR in multi webpack-dev-server/client?http://0.0.0.0:8080 webpack/hot/dev-server ../packages/cli/~/hops-config/shims/develop.js
Module not found: Error: Can't resolve 'webpack-dev-server/client?http://0.0.0.0:8080' in '/Users/norbert.pabian/development/hops/demo'
@ multi webpack-dev-server/client?http://0.0.0.0:8080 webpack/hot/dev-server ../packages/cli/~/hops-config/shims/develop.js
ERROR in multi webpack-dev-server/client?http://0.0.0.0:8080 webpack/hot/dev-server ../packages/cli/~/hops-config/shims/develop.js
Module not found: Error: Can't resolve 'webpack/hot/dev-server' in '/Users/norbert.pabian/development/hops/demo'
@ multi webpack-dev-server/client?http://0.0.0.0:8080 webpack/hot/dev-server ../packages/cli/~/hops-config/shims/develop.js
ERROR in multi webpack-dev-server/client?http://0.0.0.0:8080 webpack/hot/dev-server ../packages/cli/~/hops-config/shims/develop.js
Module not found: Error: Can't resolve 'babel-loader' in '/Users/norbert.pabian/development/hops/demo'
@ multi webpack-dev-server/client?http://0.0.0.0:8080 webpack/hot/dev-server ../packages/cli/~/hops-config/shims/develop.js
webpack: Failed to compile.
I wanted to find out how the config option bootstrapServer
is supposed to be used and couldn't find documentation on that. Is that internal API or should it be mentioned in packages/config/README.md?
If this is option is regarded as internal, comment and close this issue, otherwise please add an entry with a short description to the table in packages/config/README.md.
We currently have two server-ish packages hops-server
and hops-express
. Considering how highly integrated the two are, that seems a bit bloaty.
It appears we might be able to consolidate them into a single package, hops-express
.
The store enhancer is missing some configuration:
https://github.com/zalmoxisus/redux-devtools-extension#2-use-with-redux
No support for styled components...
Integrate https://github.com/foosbyte/kicker-trainer/tree/hops/packages/hops-styled-components and consider supporting arbitrary HTML head extensions.
hops-config
requires webpack-manifest-plugin@^1.2.1
.
We ran yarn upgrade
which surprisingly (at least for me) also appears to upgrade supdependencies even when dependencies are already at the latest version.
Running the upgrade caused an upgrade of webpack-manifest-plugin
to version 1.3.0
, which then causes hops to not include assets in the template anymore.
The release notes for 1.3.0 also state: make sure manifest writes don't overlap
which sounds suspicous.
We only tested dev mode.
It used to be possible to start a production mode Express server without a Hops built middleware. This is now impossible (https://github.com/xing/hops/blob/master/packages/express/app.js#L33).
Move the check for the existence of the middleware to hops-local-cli
and only bail if HOPS_MODE
is not static and the middleware is missing.
Paging @matthias-reis, @ZauberNerd
The current hops-template-react
contains flow type annotations.
Remove flow support and flow types from current template hops-template-react
.
At the moment hops-lambda serves static assets (such as JS, CSS, images) via Express.js (express.static()
). This means that for each asset that is being requested we have to execute the Lambda function again, which, for a cold-start could be 1-2 seconds. Also Express.js has a latency when serving assets.
We should figure out how we can deploy static assets to S3 during build/deployment and serve them directly through S3 (we probably need to enable static website hosting mode and CORS in S3).
For deployments without a custom domain we need to be able to specify the base url of the assets in hops (instead of just the basePath
configuration) and then we can point the assets directly to the S3 url (https://examplebucket.s3-website-eu-central-1.amazonaws.com/
).
For deployments with a custom domain we need to figure out how we can make assets available on that custom domain.
Use a different subdomain (assets.mydomain.com/
) - also requires hops to be able to specify a base url instead of a base path to serve assets from. Example S3 and Route53 configuration: http://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html
Investigate how we can exclude a path (e.g. /assets
) from the otherwise greedy API Gateway proxy integration and send requests to that path to the S3 bucket instead.
aws_service
or http
as integration type.Given I have a package.json with
"config": {
"hops": {
"extends": "./hops.config.js"
}
}
When I set different developConfig
(based on environment variables) in my ./hops.config.js
Then I expect these configurations to be picked up by hops
But hops keeps using the default value because the extends field is not resolved before develop, build and node configurations are used (as far as I understand the code).
resolve extends
field before using anything from the config.
The cli output throughout all cli parts is unfortunately not really consistent combining blank console.log
statements with outputs of other parts like webpack.
I'd like to work on that and create a low level logging solution that
debug
, info
, warn
and error
build took 42.2s
)A Lambda cold start could take quite some time. For background tasks this won't be an issue, but since hops-lambda renders user-facing websites, we should try to find a way to keep a Lambda function "warm".
By setting up a Cloudwatch scheduled event that invokes the Lambda function periodically, we can try to prevent the container from shutting down, which should keep the response times low.
I'd like to use separate postcss packages within hops/packages/config/loaders/postcss.js
instead of postcss-cssnext
. Currently, we use cssnext@^2.11.0
. This version uses some older versions for some of the postcss packages included which lead to a strange bug caused by [email protected]
and pseudo elements/media query combinations.
Seeing that MoOx/postcss-cssnext#384 and MoOx/postcss-cssnext#385 seem rather unlikely to be merged soon(ish), I'd propose to replace cssnext with the different plugins bundled in it (excluding the ones deemed unnecessary in MoOx/postcss-cssnext#385) just as standalone ones in the order currently used in cssnext. We could then update all of the packages to the latest versions as planned in the cssnext pull requests.
This removes the "middleman" function (and convenience) of cssnext – but enables us to quickly update the single packages if necessary and thus get the latest fixes per packages on an individual package basis if needs be.
As soon as [email protected]
is released, we can check again and re-introduce it in favor of the single packages approach.
Also, I'd get rid of some superfluous packages (mixins
, advanced-variables
, nested
, atroot
, property-lookup
, extend
) since the functionality is either over the top or implemented within CSS modules etc. in the current setup anyways and can thus be refactored to use already existing functionality.
This would result in:
var options = {browsers: hopsConfig.browsers};
var postcssLoaderOptions = {
plugins: function (loader) {
return [
require('postcss-import')({
addModulesDirectories: hopsConfig.modules
}),
require('postcss-advanced-variables')(),
require("postcss-custom-properties")(options),
require("postcss-apply")(options),
require("postcss-calc")(options),
require("postcss-image-set-polyfill")(options),
require("postcss-nesting")(options),
require("postcss-custom-media")(options),
require("postcss-media-minmax")(options),
require("postcss-custom-selectors")(options),
require("postcss-attribute-case-insensitive")(options),
require("postcss-color-rebeccapurple")(options),
require("postcss-color-hwb")(options),
require("postcss-color-hsl")(options),
require("postcss-color-rgb")(options),
require("postcss-color-gray")(options),
require("postcss-color-hex-alpha")(options),
require("postcss-color-function")(options),
require("postcss-font-family-system-ui")(options),
require("postcss-font-variant")(options),
require("postcss-initial")(options),
require("postcss-selector-matches")(options),
require("postcss-selector-not")(options),
require("postcss-pseudo-class-any-link")(options),
require("postcss-replace-overflow-wrap")(options),
require("autoprefixer")(options),
require('postcss-reporter')()
];
}
};
and would change the package.json
to look like this – comparison to currently used version shamelessly dumped next to the to-be-used version:
…
"postcss": "^6.0.2", // 5.2.17
"postcss-custom-properties": "^6.0.1", // 5.0.2
"postcss-apply": "^0.8.0", // 0.3.0
"postcss-calc": "^6.0.0", // 5.3.1
"postcss-image-set-polyfill": "^0.3.5", // 0.3.5
"postcss-nesting": "^4.0.1", // 2.3.1
"postcss-custom-media": "^6.0.0", // 5.0.1
"postcss-media-minmax": "^3.0.0", // 2.1.2
"postcss-custom-selectors": "^4.0.1", // 3.0.0
"postcss-attribute-case-insensitive": "^2.0.0", // 1.0.1
"postcss-color-rebeccapurple": "3.0.0", // 2.0.1
"postcss-color-hwb": "^3.0.0", // 2.0.1
"postcss-color-hsl": "^2.0.0", // 1.0.5
"postcss-color-rgb": "^2.0.0", // 1.1.4
"postcss-color-gray": "^4.0.0", // 3.0.1
"postcss-color-hex-alpha": "^3.0.0", // 2.0.0
"postcss-color-function": "^4.0.0", // 2.0.1
"postcss-font-family-system-ui": "^2.0.1", // 1.0.2
"postcss-font-variant": "^3.0.0", // 2.0.1
"postcss-initial": "^2.0.0", // 1.5.3
"postcss-selector-matches": "^3.0.1", // 2.0.5
"postcss-selector-not": "^3.0.1", // 2.0.0
"postcss-pseudo-class-any-link": "^4.0.0", // 1.0.0
"postcss-replace-overflow-wrap": "^2.0.1-0", // 1.0.0
"postcss-import": "^10.0.0",
"postcss-loader": "^2.0.6",
"postcss-reporter": "^4.0.0",
…
I guess it's a good choice to always reset or normalize styles before start creating new ones, but I guess including normalize.css as a default is kind of opinionated.
I mean that I understand this things as a part of the end product and I guess Hops goes a little too far including normalize.css as a default way of reseting styles. I may prefer sanitize.css (which I do) or a plain old reset.css, or even a custom solution.
Maybe it's better to let the users chose the best for their app? What do you think?
Continuing the discussion in #29:
The current hmre implementation is rather instable and buggy, but something new and shiny ✨ is on the horizon: react-hot-loader seems to be the way to go forward.
Let's see how things are going regarding v3.0.0 and switch as soon as a stable version hits npm.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.