I am trying to architect an extendable Web applications that allows users to build and export static websites. Similar to this site and this site, except developers can build their own custom components using HTML,CSS and Javascript and add it to the public library.
The Architecture must:
Ensure that user added components can not interfere with each other (Encapsulation)
HTML attributes have unique values (<div id="a"> remains unique to this component)
CSS is namespaced
Javascript objects are scoped and can only modify DOM elements within this component.
Enable developers to build components in simple HTML, CSS, Javascript without the need for building a React/Vue/Angular etc. JS components.
Developers can build components without worrying about encapsulation issues above. i.e. The application transforms the unsafe HTML,CSS,Javascript to one which is safe.
Ensures cross-browser compatibility
iFrames provide excellent encapsulation but have performance and device scaling issues. I have been reading about Shadow DOM, Web components but haven't been able to figure out the correct approach to build such a Web Application.
I also came across this SO Question but it seems like this is more geared toward back-end. Please correct me if I am wrong. Is there any existing framework/build tools/library that I can use? If not how should I go about building such a tool?
Related
I recently read an article about how HTML elements created with JavaScript are not picked up by the Googlebot / Google crawlers. The reason being, in its most simple form, the HTML the GoogleBot picks up is everything that is shown when you do View Page Source.
I'm about to start learning React, one of the reasons for this being that you can create template files and components, so common features such as headers and footers etc and be duplicated easily to keep your code DRY.
It worries me though that if I was to do this, the React / JSX generated HTML would effectively not be tracked by web crawlers, thus making it essentially invisible, which would create a large number of potential negatives, not least, inferior SEO.
My question therefore is - does HTML generated with React behave in the same way HTML generated with vanilla JavaScript does? I'm assuming it must do, but I can't find any proper answers to this when googling?
Many thanks,
Emily.
Reactjs is an isomorphic or Universal or environment agnostic.
You can build client side application and also server side applications.
As you are already aware of client side of it. Now you checkout the server side implementation in the below tutorial
https://scotch.io/tutorials/react-on-the-server-for-beginners-build-a-universal-react-and-node-app
you can also checkout the following boilerplates which provide SSR :
https://github.com/erikras/react-redux-universal-hot-example
https://github.com/TimoRuetten/react-ssr-boilerplate
I have a large, globalised web site (not a web app), with 50k+ pages of content which is rendered on a cluster of servers using quite straightforward NodeJS + Nunjucks to generate HTML. For 90% of the site, this is perfectly acceptable, and necessary to achieve SEO visibility, particularly in non-Google search engines which don't index JS well (Yandex, Baidu, etc)
The site is a bit clunky as complexity has increased over time, and I'd like to re-architect some of the functional components that are built mostly using progressively enhanced jQuery as they are quite clunky. I've been looking at React for this with the Redux implementation of the Flux pattern.
Now my question is simply around the following - nearly 100% of the tutorials assume I'm building some sort of SPA, which I'm not. I just want to build a set of containerised reusable components that I can plug into replace the jQuery components. Oh, they have to be WCAG AA/508 accessible as well
Does React play well with being retrofitted into websites and are there any specific considerations around SEO, bootstrapping, accessibility? Examples of implementations or tutorials would be appreciated.
You can mount react component to any DOM Node on your page, so it makes it easy to insert components in statically generated content.
Most of search engines like google would wait for js files to load before they index the page so it will index a page with react component perfectly fine. However if you want to be 100% sure that your page rendered correctly by all crawling bots you have to take a look at react server rendering. If you already use NodeJS for a backend it should not be a big problem.
I never encountered with that kind of problem but my best guess would be to use ReactDOMServer.renderToString to render component on the server and then replace a node in your static html layout. The implementation would depend on you template lang you use. You can use something like handlebars to dynamically create halpers from React Components. So in your static html page you would be able to use them as {{my-component}} But it's only my speculations on that subject, may be there is more elegant solution.
Here is the article that could help.
You'll be happy to know that this is all possible through something called isomorphic javascript. Basically you'll just use React and jsx to render HTML on the server which is then sent to the browser as a fully built web page. This does not assume your app is an SPA, rather that you'll have multiple endpoints for rendering different pages, much like you already have probably.
The benefit here is that you can use the React/Redux architecture but still allow you site to be indexable by crawlers, as requests to your app will yield static pages, not a single page with lots of JS to make it work. You're also free to gradually refactor by converting your Nunjucks rendered endpoints to React one at a time, instead of a big jump to SPA land.
Here's a good tutorial I found on making isomorphic React apps with node:
https://strongloop.com/strongblog/node-js-react-isomorphic-javascript-why-it-matters/
EDIT: I may have misread your actual desire which is to inject React components into your existing web pages. This is also possible, you'll probably want to use ReactDOM to render your components to static markup, and then you can inject that markup string into your Nunjucks via templating.
The idea of web components is to modularize the web regardless of what framework you use.
The Polymer project promise the possibility to create web components, not to be a framework, so it should be possible to use it with any framework. More than that, I should be able to just download the elements from the element catalog and use it without the polymer library, just with the webcomponents.js.
I recognize that this is an ongoing project and most of browser's vendors are still developing the web components requirements, but what I'm concluding so far is that the Polymer is becoming a new framework as I cannot use their elements without the Polymer library and the use with framework as Angular 2 is not yet working well.
Is that a way to use web components in a real modular way without all the boilerplate that the Polymer suggest?
TL;DR;
Polymer does not break the modularity merely by the fact that it's required to use Web Components built with it. It is just a library, albeit opinionated, used to implement custom elements.
These elements are however still independent modules. All of Polymer stuff should be hidden inside a component and not interfere with the outside.
Long read
The idea of web components is to modularize the web regardless of what framework you use
In a sense, yes. Though Web Components target to modularize the DOM really. For general modularization, there are ES6 modules IMO.
The Polymer project promise the possibility to create web components, not to be a framework, so it should be possible to use it with any framework.
I'm not sure what you expect from Polymer and Web Components in general. The modularity of Web Components come from the fact that when used, they are just an ordinary part of the DOM tree. Any existing library can work with that. Any Web Component is just a HTML element and exposes a uniform interface: attributes and events. What Polymer does is add some niceties on top of that so that you can enjoy data-binding, simpler custom element declarations, simpler events API, styling polyfill, shady DOM and more.
It's a dependency like any other and should not stop you from using Polymer (or Bosonic, or x-tag, or basic-web-components) with any other web framework.
More than that, I should be able to just download the elements from the element catalog and use it without the polymer library, just with the webcomponents.js.
Where did you read that? Also, is it a problem that polymer.html is required for the components to work? You may get the same with other Web Components libraries.
I recognize that this is an ongoing project and most of browser's vendors are still developing the web components requirements.
I believe there is a need of clarification. The vendors implement the Web Components spec and where it isn't ready, webcomponents.js fill in the blanks. Just as I write above however, Polymer is a little bit more, because it gives you more than pure specs.
Is that a way to use web components in a real modular way without all the boilerplate that the Polymer suggest?
Not sure what is the bolierplate that you refer to, but yes, you can write Web Components in plain javascript (or in a minimal dependencies fashion) but you will lose some of the sugar that Web Components give you. It is just like arguing that one shouldn't use jQuery, because all that it does can be done without it.
What are strengths and weaknesses of the
sap.m.Shell
and
sap.m.App
as container for an SAPUI5 application wrapper?
I currently use non of them, but I see the advantages.
SAP best practise is to use one of them or nest them as shell > app. What are strengths and weaknesses of the approaches?
sap.m.Shell: The Shell control can be used as root element of applications, it can contain an App or SplitApp control. The Shell provides some overarching functionality for the overall application and takes care of visual adaptation, like a frame around the App, on desktop browser platforms. Gives interface to logout,set homebackgroud and other stuff. App is an aggregation for shell. Basically allows to have user level settings and so on
sap.m.App : App is the root element of a UI5 mobile application. It inherits from NavContainer and thus provides its navigation capabilities. It also adds certain header tags to the HTML page which are considered useful for mobile apps.
This acts like an container for your views with navigation features.
Best Practice: To nest them as app inside a shell. So that you have clear separation between apps and under one shell. Shell provides more features than sap.m.App though you can achieve them in crude way. According to me nesting them is best solution.
We're impressed with the integration and best practices that BoilerplateJS provides but the documentation is definitely lacking, especially for new RequireJS users.
We're a team of 5, each with different skill sets and one of the attractive points of BoilerplateJS is the ability to isolate UI components.
From the sample scaffolding, it's clear how we can unit-test each component separately. However, we're unclear how we can do this during development:
Developer A creates component structure and view model (tested) and passes it to Developer B
Developer B develops CSS and possibly animation for the component
Developer A and/or B integrate the component into the rest of the website and further test integration
How is it possible to achieve (2)? i.e. allow designers and developers to work on an isolated component - what is the recommended way to load the component so it can developed/debugged/tested?
About CSS
A UI component has roughly 3 parts: Structure (HTML), Presentation (CSS), Behavior (JS). A common way of handling is developers focusing on the Structure and Logic where designers work on the presentation.
This is how we developed the sample application of boilerplatejs. For example, the Menu, Theme and Localization components were developed by developers as a simple 'unordered lists' which looked like below exactly when they completed it (just delete the theme css link via Chrome Developer Tools and you will see the same):
Then designers took the ugly UI and created a theme that position and render these lists in a professional manner (we developed 2 themes stored at src/modules/baseModule/theme). It is of course hard for the developers to just deliver something that ugly, but they need to trust the ability of the designers to do their job. I'm sure you use a source control tool that allows different team members to work on the same component even simultaneously.
If you want the theming to be a prominent feature, I recommend minimizing component specific CSS files. Otherwise you might not be able to create different themes that completely changes the layout and look-n-feel of your components. Downside of not having component local css is the fact that components are not really self contained without 'presentation'. I'm still struggling to answer this question properly, any ideas/help is appreciated! See my related question on this below:
global CSS theming combination with component specific local stylesheets
Anyway there are several ways you may add CSS to your components, have a look at this question where these different ways are discussed.
Adding external CSS file to a BoilerplateJS project
Now about embedding components...
If you want the components embedded in to some other webpage, you can use the DOMController of boilerplate for that. For example, lets say you need to embed the 'departments (src/modules/sampleModule1/departments)' component to some other website. You will have to add a DomController in addition to already existing UrlController (UrlController respond to browser URL changes) to the module (src/modules/sampleModule1/module.js).
//crate a dom controller that searchs within whole document body
var domController = new Boiler.DomController($("body"));
domController.addRoutes({
//look for elements with id 'department_comp' and embed the department component
'#department_comp' : new DepartmentComponent(context),
});
domController.start();
Now on your webpage or on external site place a div or a section element for the DomController to embed department.
<section id="department_comp"></section>
Of course there are two things you need to take care of:
1) Your web page needs to have boilerplatejs runtime in it. This means all your third party JS libraries and theme CSS file should be statically added to the web page. (We are working around this, with v0.2-stable we expect to release a bootstrapper that can do all that with a single script declaration)
2) If your component uses JSON services from a different domain, you will have to address cross domain HTTP requests either with JSONp or CORS. But if your REST services are hosted on the same domain, you dont have to worry about this.