Webpack: How to split your bundles
To keep JavaScript sources small, it can sometimes make sense to split your webpack bundles. For example, if your website uses some large JavaScript library – say TinyMCE – which is only required on some selected pages, it makes sense to only load that library when necessary.
In modern webpack this is easily doable by using the asynchronous import
function.
Say we have an unpoly compiler that sets up TinyMCE like this (code is somewhat simplified):
// TinyMCE as part of the main bundle!
import tinymce from 'tinymce/tinymce'
// U...
Capybara: Testing file downloads
Download buttons can be difficult to test, especially with Selenium. Depending on browser, user settings and response headers, one of three things can happen:
- The browser shows a "Save as..." dialog. Since it is a modal dialog, we can no longer communicate with the browser through Selenium.
- The browser automatically downloads the file without prompting the user. For the test it looks like nothing has happened.
- The browser shows a binary document in its own window, like a PDF. Capybara/Selenium freaks out because there is no HTML docum...
Webpack(er): Analyze the size of your JavaScript components
We're always striving towards keeping our website's JavaScript as small as possible.
If you're using webpack(er), you can use the webpack-bundle-analyzer plugin to get a good overview, which of your JavaScript modules take up how much space, and where you can optimize.
To use it, add it via npm or yarn
yarn add webpack-bundle-analyzer
Then add this to your environment.js
:
// Uncomment this code to show statistics of bundle sizes. Generated file will automatically...
SameSite cookies
TL;DR Most web applications do not require action on this. SameSite=None
(old browser default) will continue to work, and SameSite=Lax
(new Chrome default, gradually rolled out) is an even better default for cookies. Set SameSite=Strict
only for extra security in special cases (see below). If your application is rendered in an iframe (e.g. a video player or some news stream), you need to configure its relevant cookies as SameSite=None
.
The SameSite
cookie attribute targets **c...
Webpacker: Side effects of using window.* within the ProvidePlugin
Some older Node modules rely on window.jQuery
to be present. One suggested solution is to use this config in the app/config/webpack/environment.js
:
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
})
)
module.exports = environment
This will work. But a side effect is that the fo...
How to test Autoprefixer and CSSnext in PostCSS
PostCSS is a tool for transforming styles with JS plugins. In Webpacker you can configure the plugins and their settings via the postcss.config.js
file. Make sure that postcss-loader
is part of your package.json
.
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009'
},
stage: 3
})
]
}
Note: Stage 3 means you can use all CSS features that ar...
Webpack: How to avoid multiple versions of jQuery
To avoid multiple versions of a package, you can manually maintain a resolutions
section in your package.json
. We recommend you to do this for packages like jQuery. Otherwise the jQuery library attached to window
might not include the functions of your packages that depend on jQuery.
Note: This is only an issue in case you want to use a package functionality from window
e.g. $(...).datepicker()
from your dev console or any other javascript within the application.
Background
By default yarn will create a folder node_modules
...
Migration from the Asset Pipeline to Webpacker
This is a short overview of things that are required to upgrade a project from the Asset Pipeline to Webpacker. Expect this upgrade to take a few days even the diff is quite small afterwards.
Preparations
1. Find all libraries that are bundled with the asset pipeline. You can check the application.js
and the application.css
for require
and import
statements. The source of a library is most often a gem or a vendor directory.
2. Find an working example for each library in the application and write it down.
3. Find out the ver...
HTML emails with inline stylesheets and webpacker
Many mail clients do not support external style sheets. Some even require all styling inline, which means you'll have to do your styling inline. For Rails applications, you can use Roadie or premailer, which lets you keep your well-structured CSS files and do the inlining for you.
Since Roadie is now in passive maintenance mode, we go with premailer:
Include premailer in your Gemfile:
gem 'premailer-ra...
Using local fonts with Webpack / Webpacker
When we want to use our own (or bought) fonts in an application with Webpack(er), we have two options. We can
- put the fonts directly into your Webpack's assets folder or
- write an npm package with an own sass file that can be imported from the Webpack manifest.
Load fonts from your assets folder
The first option turns out to be straightforward: Import the stylesheets in the index.js of the pack you're using:
// webpack_source_path/application/index.js
import './stylesheets/reset'
import...
Upgrade guide for moving a Rails app from Webpack 3 to Webpack 4
Webpacker is Rails' way of integrating Webpack, and version 4 has been released just a few days ago, allowing us to use Webpack 4.
I successfully upgraded an existing real-world Webpack 3 application. Below are notes on everything that I encountered.
Note that we prefer not using the Rails asset pipeline at all and serving all assets through Webpack for the sake of consistency.
Preparations
- Remove version locks in
Gemfile
forwebpacker
- Remove version locks in
package.json
forwebpack
andwebpack-dev-server
- Install by ca...
Cheat Sheet for the modern DOM API
See the attached link for a useful overview of modern (and classic) DOM API methods, like matches
, contains
, append
, cssText
, etc.
You will still need to look up some documentation, e.g. on how to modify a ClassList
, but it's still better than browsing interfaces and superclasses of Element
on MDN without knowing what to look for.
When coming from jQuery, also see the card on JavaScript without jQuery. This card includes a link to [You Don't Need jQuery](https://github.com/nefe/You-Dont-Need-jQuery/blob/maste...
JavaScript without jQuery
This is a presentation from 2019-01-21.
Summary
- We want to move away from jQuery in future projects
- Motivations are performance, bundle size and general trends for the web platform.
- The native DOM API is much nicer than it used to be, and we can polyfill the missing pieces
- Unpoly 0.60.0 works with or without jQuery
Is jQuery slow?
From: Sven
To: unpoly@googlegroups.com
Subject: performance on smartphones and tablets
Hello
I just used your framework in one project and must say,
I am really pleased with it -- but o...
Rails asset pipeline: Using ESNext without a transpiler
If your app does not need to support IE11, you can use most ES6 features without a build step. Just deliver your plain JavaScript without transpilation through Babel or TypeScript, and modern browsers will run them natively.
Features supported by all modern browsers include:
- fat arrow functions (
() => { expr }
) -
let
/const
class
-
async
/await
- Promises
- Generators
- Symbols
- Rest arguments (
...args
) - Destructuring
You won't be able to use import
and export
, or use npm modules.
See this [ES6 compatibility mat...
How to: Use Ace editor in a Webpack project
The Ace editor is a great enhancement when you want users to supply some kind of code (HTML, JavaScript, Ruby, etc).
It offers syntax highlighting and some neat features like auto-indenting.
For Webpack 3+
Integrate as described in the documentation. For example load ace Editor like this:
function loadAceEditor() {
return import(/* webpackChunkName: "ace" */ 'ace-builds/src-noconflict/ace').then(() => {
return import(/* webpackChunkName: "ace" */ 'ace-builds/webpack-r...
Regular tasks for long-running projects
When projects run for many years, they require special regular maintenance to stay fresh. This kind of maintenance is usually not necessary for small or quick projects, but required to keep long-running projects from getting stale.
You should be able to fit this into a regular development block.
Quarterly
Check which libraries need updating
As time goes by, libraries outdate. Check your software components and decide if any of it needs an update. Your main components (e.g. Ruby, Rails, Unpoly) should always be reasonably up to da...
How to access before/after pseudo element styles with JavaScript
Accessing pseudo elements via JavaScript or jQuery is often painful/impossible. However, accessing their styles is fairly simple.
Using getComputedStyle
First, find the element in question.
let element = document.querySelector('.my-element') // or $('.my-element').get(0) when using jQuery
Next, use JavaScript's getComputedStyle
. It takes an optional 2nd argument to filter for pseudo elements.
let style = window.getComputedStyle(element, '::before')
let color = style.getPropertyValue('background-color...
jQuery: How to remove classes from elements using a regular expression
jQuery's removeClass
removes the given class string from an element collection. If you want to remove multiple/unknown classes matching a given pattern, you can do that.
For example, consider a DOM node for the following HTML. We'll reference it by $element
below.
<div class="example is-amazing is-wonderful"></div>
Option A: Selecting classes, then removing them
You can iterate over existing classes, and select matching ones. The example below is ES6, on ES5 could write something similar using jQuery.grep
.
let classes ...
JavaScript basics tutorial: 33 Concepts Every JavaScript Developer Should Know
This repository was created with the intention of helping developers master their concepts in JavaScript. It is not a requirement, but a guide for future studies. It is based on an article written by Stephen Curtis.
Table of Contents
- Call Stack
- Primitive Types
- Value Types and Reference Types
- Implicit, Explicit, Nominal, Structuring and Duck Typing
- == vs === vs typeof
- Function Scope, Block Scope and Lexical Scope
- Expression vs Statement
- IIFE, Modules and Namespaces
- Message Queue and Event Loop
- setTimeout, setInte...
JavaScript: Sharing content with the native share dialog
Mobile Chrome and Safari support the "web share API" which allow you to use the native share functionality of an Android or iOS phone. Some desktop OSs like Windows or MacOS also support native share dialogs. See Can I Use for a detailed support matrix.
When clicking a share button using this API, the browser will automatically show all installed applications that support content sharing, such as Whatsapp, Facebook, Twitter, e-mail etc.
The API is extremely simple to use:
if ...
Accessing Rails config in webpack(er)
It is possible to access Rails config (for example secrets) from within your webpack bundles, thanks to rails-erb-loader. When using webpacker, the setup is like this:
-
Install
rails-erb-loader
:yarn add rails-erb-loader
-
Add this to your
config/webpacker/environment.js
:environment.loaders.prepend('erb', { test: /\.erb$/, enforce: 'pre', use: [{ loader: 'rails-erb-loader', }] })
-
Start using erb. For examp...
Does <html> or <body> scroll the page?
TL;DR: All modern browsers default to using the <html>
element as the main document viewport. In CSS, prefer to set overflow
properties to html
(or :root
).
Scrolling the main viewport with JavaScript
The browser's main document viewport is also scrollable by default. The element that corresponds to the main viewport is either <html>
(document.documentElement
) or <body>
(document.body
). Which one depends on the browser.
When you want to update the current `sc...
Minify Font Awesome fonts with webpack
Font Awesome 5 is a comprehensive solution for vector icons on your website.
Originally, Font Awesome came as an icon font (plus stylesheets), but recently it can also be used as a pure JavaScript solution (which will render icons as inline <svg>
tags), or even as SVG sprites.
All solutions have their pros and cons:
Icon font:
- little CPU load (no JavaScript)
- fonts are relatively large
- 1 extra HTTP request
Javascript + inline SVG:
- higher CPU load (needs to watch the DOM via mutation observers to ad...
Colcade is a lightweight Masonry alternative
Masonry is a famous library to dynamically arrange a grid of items that have different aspect ratio, like horizontal and vertical images.
Colcade is an alternative masonry-layouting library, developed by the same developer, but with a more modern approach.
It is said to have better performance while being smaller and having no dependencies. It automagically detects jQuery and defines a jQuery initializer, if present.
However, it offers [a few less features](https:...