How to use CustomElement v1 polyfill in a webpack/babel build? - ios

I'm having some trouble getting this WebComponents polyfill + native-shim to work right across all devices, though webpack.
Some background on my setup:
* Webpack2 + babel-6
* app is written in ES6, transpiling to ES5
* imports a node_module package written in ES6, which defines/registers a CustomElement used in the app
So the relevant webpack dev config looks something like this:
const config = webpackMerge(baseConfig, {
entry: [
'webpack/hot/only-dev-server',
'#webcomponents/custom-elements/src/native-shim',
'#webcomponents/custom-elements',
'<module that uses CustomElements>/dist/src/main',
'./src/client',
],
output: {
path: path.resolve(__dirname, './../dist/assets/'),
filename: 'app.js',
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
options: {
cacheDirectory: true,
},
include: [
path.join(NODE_MODULES_DIR, '<module that uses CustomElements>'),
path.join(__dirname, '../src'),
],
},
],
},
...
key take aways:
* I need CustomElement poly loaded before <module that uses CustomElements>
* I need <module that uses CustomElements> loaded before my app soure
* <module that uses CustomElements> is ES6 so we're transpiling it ( thus the include in the babel-loader).
The above works as-expected in modern ES6 browsers ( IE desktop Chrome ), HOWEVER
it does not work in older browsers. I get the following error in older browsers, for example iOS 8:
SyntaxError: Unexpected token ')'
pointing to the opening anonymous function in the native-shim pollyfill:
(() => {
'use strict';
// Do nothing if `customElements` does not exist.
if (!window.customElements) return;
const NativeHTMLElement = window.HTMLElement;
const nativeDefine = window.customElements.define;
const nativeGet = window.customElements.get;
So it seems to me like the native-shim would need to be transpiled to ES5:
include: [
+ path.join(NODE_MODULES_DIR, '#webcomponents/custom-elements/src/native-shim'),
path.join(NODE_MODULES_DIR, '<module that uses CustomElements>'),
path.join(__dirname, '../src'),
],
...but doing so now breaks both Chrome and iOS 8 with the following error:
app.js:1 Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function.
at new StandInElement (native-shim.js:122)
at HTMLDocument.createElement (<anonymous>:1:1545)
at ReactDOMComponent.mountComponent (ReactDOMComponent.js:504)
at Object.mountComponent (ReactReconciler.js:46)
at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
at Object.mountComponent (ReactReconciler.js:46)
at Object.updateChildren (ReactChildReconciler.js:121)
at ReactDOMComponent._reconcilerUpdateChildren (ReactMultiChild.js:208)
at ReactDOMComponent._updateChildren (ReactMultiChild.js:312)
.. which takes me to this constructor() line in the native-shim:
window.customElements.define = (tagname, elementClass) => {
const elementProto = elementClass.prototype;
const StandInElement = class extends NativeHTMLElement {
constructor() {
Phew. So it's very unclear to me how we actually include this in a webpack based build, where the dependency using CustomElements is ES6 ( and needs transpiling).
Transpiling the native-shim to es5 doesn't work
using the native-shim as-is at the top of the bundle entry point doesn't work for iOS 8, but does for Chrome
not including the native-shim breaks both Chrome and iOS
I'm really quite frustrated with web components at this point. I just want to use this one dependency that happens to be built with web components. How can I get it to work properly in a webpack build, and work across all devices? Am I missing something obvious here?
My .babelrc config for posterity sake (dev config most relevant):
{
"presets": [
["es2015", { "modules": false }],
"react"
],
"plugins": [
"transform-custom-element-classes",
"transform-object-rest-spread",
"transform-object-assign",
"transform-exponentiation-operator"
],
"env": {
"test": {
"plugins": [
[ "babel-plugin-webpack-alias", { "config": "./cfg/test.js" } ]
]
},
"dev": {
"plugins": [
"react-hot-loader/babel",
[ "babel-plugin-webpack-alias", { "config": "./cfg/dev.js" } ]
]
},
"dist": {
"plugins": [
[ "babel-plugin-webpack-alias", { "config": "./cfg/dist.js" } ],
"transform-react-constant-elements",
"transform-react-remove-prop-types",
"minify-dead-code-elimination",
"minify-constant-folding"
]
},
"production": {
"plugins": [
[ "babel-plugin-webpack-alias", { "config": "./cfg/server.js" } ],
"transform-react-constant-elements",
"transform-react-remove-prop-types",
"minify-dead-code-elimination",
"minify-constant-folding"
]
}
}
}

I was able to achieve something similar with the .babelrc plugin pipeline below. It looks like the only differences are https://babeljs.io/docs/plugins/transform-es2015-classes/ and https://babeljs.io/docs/plugins/transform-es2015-classes/, but I honestly can't remember what problems those were solving specifically:
{
"plugins": [
"transform-runtime",
["babel-plugin-transform-builtin-extend", {
"globals": ["Error", "Array"]
}],
"syntax-async-functions",
"transform-async-to-generator",
"transform-custom-element-classes",
"transform-es2015-classes"
]
}

Related

Error loading appsettings.Production.json due to digest integrity issue

I'm developing a Blazor WebAssembly app with PWA enabled, and with files appsettings.json, appsettings.Development.json and appsettings.Production.json. The last one is empty because it would contain secrets to replace when production environment is deployed to a kubernetes cluster.
I'm using k8s to deploy, and a Secret resource to replace the empty appsettings.Production.json file by an encrypted file, into a nginx based container with the published blazor app inside.
Now I'm getting this issue in the browser:
When the application was built using docker build in a CI pipeline, the file was an empty json file, and got a SHA computed that does not match then one computed by the build process.
My question is: How can I replace the appsettings.Production.json during deployment, much later than the build process, and don't have the integrity test failed over that file?
The file blazor.boot.json does not contain any SHA for the appsetting.Production.json file:
{
"cacheBootResources": true,
"config": [
"appsettings.Development.json",
"appsettings.json",
"appsettings.Production.json"
],
"debugBuild": false,
"entryAssembly": "IrisTenantWeb",
"icuDataMode": 0,
"linkerEnabled": true,
"resources": {
"assembly": {
"Azure.Core.dll": "sha256-rzNx\/GlDpiutVRPzugT82owXvTopmiixMar68xLA6L8=",
// Bunch of .dlls,
"System.Private.CoreLib.dll": "sha256-S7l+o9J9ivjCunMa+Ms\/JO\/kVaXLW8KTAjq1eRjY4EA="
},
"lazyAssembly": null,
"pdb": null,
"runtime": {
"dotnet.timezones.blat": "sha256-SQvzbzBfueaAxSKIKE1khBH02NH2MJJaWDBav\/S5MSs=",
"dotnet.wasm": "sha256-YXYNlLeMqRPFVpY2KSDhleLkNk35d9KvzzwwKAoiftc=",
"icudt.dat": "sha256-m7NyeXyxM+CL04jr9ui1Z6pVfMWwhHusuz5qNZWpAwA=",
"icudt_CJK.dat": "sha256-91bygK5voY9lG5wxP0\/uj7uH5xljF9u7iWnSldT1Z\/g=",
"icudt_EFIGS.dat": "sha256-DPfeOLph83b2rdx40cKxIBcfVZ8abTWAFq+RBQMxGw0=",
"icudt_no_CJK.dat": "sha256-oM7Z6aN9jHmCYqDMCBwFgFAYAGgsH1jLC\/Z6DYeVmmk=",
"dotnet.5.0.5.js": "sha256-Dvb7uXD3+JPPqlsw2duS+FFNQDkFaxhIbSQWSnhODkM="
},
"satelliteResources": null
}
}
But the service-worker-assets.js file DOES contains a SHA computed for it:
self.assetsManifest = {
"assets": [
{
"hash": "sha256-EaNzjsIaBdpWGRyu2Elt6mv3X+48iD9gGaSN8xAm3ao=",
"url": "appsettings.Development.json"
},
{
"hash": "sha256-RIn54+RUdIs1IeshTgpWlNViz\/PZ\/1EctFaVPI9TTAA=",
"url": "appsettings.json"
},
{
"hash": "sha256-RIn54+RUdIs1IeshTgpWlNViz\/PZ\/1EctFaVPI9TTAA=",
"url": "appsettings.Production.json"
},
{
"hash": "sha256-OV+CP+ILUqNY7e7\/MGw1L5+Gi7EKCXEYNJVyBjbn44M=",
"url": "css\/app.css"
},
// ...
],
"version": "j39cUu6V"
};
NOTE: You can see that both appsettings.json and appsettings.Production.json have the same hash because they are both the empty json file {}. But in production the second one is having a computed hash of YM2gjmV5... and issuing the error.
I can't have different build processes for different environments, because that would not ensure using the same build from staging and production. I need to use the same docker image but replacing the file at deployment time.
I edited the wwwroot/service-worker.published.js file, which first lines are as follow:
// Caution! Be sure you understand the caveats before publishing an application with
// offline support. See https://aka.ms/blazor-offline-considerations
self.importScripts('./service-worker-assets.js');
self.addEventListener('install', event => event.waitUntil(onInstall(event)));
self.addEventListener('activate', event => event.waitUntil(onActivate(event)));
self.addEventListener('fetch', event => event.respondWith(onFetch(event)));
const cacheNamePrefix = 'offline-cache-';
const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`;
const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ];
const offlineAssetsExclude = [ /^service-worker\.js$/ ];
async function onInstall(event) {
console.info('Service worker: Install');
// Fetch and cache all matching items from the assets manifest
const assetsRequests = self.assetsManifest.assets
.filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url)))
.filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url)))
.map(asset => new Request(asset.url, { integrity: asset.hash }));
await caches.open(cacheName).then(cache => cache.addAll(assetsRequests));
}
...
I added an array of patterns, similar to offlineAssetsInclude and offlineAssetsExclude to indicate which files I want to skip integrity checks.
...
const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ];
const offlineAssetsExclude = [ /^service-worker\.js$/ ];
const integrityExclude = [ /^appsettings\.Production\.json$/ ]; // <-- new variable
Then at onInstall, instead of always returning a Request with integrity set, I skipped it for excluded patterns:
...
async function onInstall(event) {
console.info('Service worker: Install');
// Fetch and cache all matching items from the assets manifest
const assetsRequests = self.assetsManifest.assets
.filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url)))
.filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url)))
.map(asset => {
// Start of new code
const integrity =
integrityExclude.some(pattern => pattern.test(asset.url))
? null
: asset.hash;
return !!integrity
? new Request(asset.url, { integrity })
: new Request(asset.url);
// End of new code
});
await caches.open(cacheName).then(cache => cache.addAll(assetsRequests));
}
...
I'll wait for others to comment and propose other solutions, because the ideal response would set the correct SHA hash to the file, instead of ignoring it.

RequireJS inconsistent error with async and google maps api when using identity services

I'm working on a .NET 5 based MVC app. I wanted to switch it to TypeScript and modularize the code. The best way I found to do this is to build everything as AMD packages and use RequireJS for loading. At first glance things seem to work OK but then I started seeing errors on some pages. Any time there is an error I can do a CTRL-F5 and the page loads correctly without any error. When the error occurs, it is near instantaneous. It is not happening after 7 seconds (the default, I believe) so the "timeout" message appears to be false.
The most common error being seen is this one:
Uncaught Error: Load timeout for modules: async!https://maps.googleapis.com/maps/api/js?key={{REMOVED_API_KEY}}_unnormalized2,jquery
https://requirejs.org/docs/errors.html#timeout
at makeError (require.min.js:1)
at R (require.min.js:1)
at require.min.js:1
I'm not sure if it is just the error reporting format, but notice that there is extra text being added after the API key.
Another errors that happens at times is:
Uncaught TypeError: Cannot read property 'initializePage' of undefined
at require-config.js:48
at Object.execCb (require.min.js:1)
at e.check (require.min.js:1)
at e.<anonymous> (require.min.js:1)
at require.min.js:1
at require.min.js:1
at each (require.min.js:1)
at emit (require.min.js:1)
at e.check (require.min.js:1)
at enable (require.min.js:1)
"initializePage" is a function that is defined and usually works fine. The background information below will show how it is setup.
A third error that can appear at times:
Uncaught Error: Mismatched anonymous define() module: function(){return t.hljs}
https://requirejs.org/docs/errors.html#mismatch
at makeError (require.min.js:1)
at T (require.min.js:1)
at require.min.js:1
I can't find anything in the project with "return t.hljs", so I guess this has to be generated code.
Now comes the strangest part. This site uses Identity Management to authenticate users. If the user is not logged in, no errors are occurring.
For background, first, here is the config I'm using for RequireJS:
function requireConfig(mapsApiKey) {
var mapsUrl = "https://maps.googleapis.com/maps/api/js?key=" + mapsApiKey;
require.config({
baseUrl: '/js',
paths: {
'async': '../lib/requirejs-plugins/async.min',
'jquery': '../lib/jquery/jquery.min',
'bootstrap': '../lib/twitter-bootstrap/js/bootstrap.bundle.min',
'datatables.net': '../lib/datatables.net/jquery.dataTables.min',
'datatables.net-bs4': '../lib/datatables.net-bs4/dataTables.bootstrap4.min',
'datatables.net-responsive': '../lib/datatables.net-responsive/dataTables.responsive.min',
'datatables.net-responsive-bs4': '../lib/datatables.net-responsive-bs4/responsive.bootstrap4.min',
'jquery-validation': '../lib/jquery-validate/jquery.validate.min',
'jquery.validate.unobtrusive': '../lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min',
'select2': '../lib/select2/js/select2.min'
},
shim: {
'jquery': {
exports: 'jquery'
},
'bootstrap': {
deps: ['jquery'],
exports: 'Bootstrap'
},
'datatables.net-bs4': {
deps: ['jquery', 'bootstrap', 'datatables.net']
},
'datatables.net-responsive-bs4': {
deps: ['datatables.net-bs4', 'datatables.net-responsive']
},
'jquery.validate': {
deps: ['jquery']
},
'jquery.validate.unobtrusive': {
deps: ['jquery', 'jquery-validation']
},
'select2': {
deps: ['jquery']
}
}
});
define('gmaps', ['async!' + mapsUrl], function () { return window.google.maps; });
}
function requireSite() {
require(['site'], function (site) {
site.initializePage();
});
}
Next, here is my "libman.json" file so you can see what versions of various libraries are in use:
{
"version": "1.0",
"defaultProvider": "cdnjs",
"libraries": [
{
"library": "jquery#3.5.1",
"destination": "wwwroot/lib/jquery/"
},
{
"library": "twitter-bootstrap#4.6.0",
"destination": "wwwroot/lib/twitter-bootstrap/"
},
{
"library": "select2#4.0.13",
"destination": "wwwroot/lib/select2/"
},
{
"library": "font-awesome#5.15.2",
"destination": "wwwroot/lib/font-awesome/"
},
{
"library": "datatables.net#1.10.23",
"destination": "wwwroot/lib/datatables.net/"
},
{
"library": "datatables.net-responsive#2.2.7",
"destination": "wwwroot/lib/datatables.net-responsive/"
},
{
"library": "datatables.net-responsive-bs4#2.2.7",
"destination": "wwwroot/lib/datatables.net-responsive-bs4/"
},
{
"library": "datatables.net-bs4#1.10.23",
"destination": "wwwroot/lib/datatables.net-bs4/"
},
{
"library": "jquery-validation-unobtrusive#3.2.11",
"destination": "wwwroot/lib/jquery-validation-unobtrusive/"
},
{
"library": "jquery-validate#1.19.2",
"destination": "wwwroot/lib/jquery-validate/"
},
{
"library": "require.js#2.3.6",
"destination": "wwwroot/lib/require.js/"
},
{
"library": "requirejs-plugins#1.0.3",
"destination": "wwwroot/lib/requirejs-plugins/",
"files": [
"async.min.js",
"async.js"
]
}
]
}
Here is the identity setup section from Startup.cs:
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services
.AddAuthentication()
.AddGoogle(options =>
{
var googleAuthNSection = Configuration.GetSection("Authentication:Google");
options.ClientId = googleAuthNSection["ClientId"];
options.ClientSecret = googleAuthNSection["ClientSecret"];
});
I've been searching through various resources for over a week and although I see lots of related messages to the errors I'm seeing, none appear to be the exact pattern and none of the recommended remedies of worked. Hopefully someone out there has an idea of what interaction is going on here or can suggest an alternate pattern to get this all working.
Edit with information requested by Damian
On pages with the 'initializePage' error, only the require.js script and the script with the require setup is loading. No resources defined to require.js (including the site.js file) are being loaded and there is no attempt to load them.
CTRL-F5, and the page comes up just fine.
On pages getting the "Mismatched anonymous" error with "return t.hljs", all of the required scripts (site, jquery, bootstrap, and google-maps) are loading in under 3 ms.
CTRL-F5 fixes these pages as well.
It took a while but I finally triggered a page that had the module timeout error with google maps. On that one, the require.js and require setup scripts loaded, followed by the site.js and the async module for require. Noe of the other scripts (mentioned above) were loaded and there were no callouts to load them.

Artifactory and Jenkins - get file with newest/biggest custom property

I have generic repository "my_repo". I uploaded files there from jenkins with to paths like my_repo/branch_buildNumber/package.tar.gz and with custom property "tag" like "1.9.0","1.10.0" etc. I want to get item/file with latest/newest tag.
I tried to modify Example 2 from this link ...
https://www.jfrog.com/confluence/display/JFROG/Using+File+Specs#UsingFileSpecs-Examples
... and add sorting and limit the way it was done here ...
https://www.jfrog.com/confluence/display/JFROG/Artifactory+Query+Language#ArtifactoryQueryLanguage-limitDisplayLimitsandPagination
But im getting "unknown property desc" error.
The Jenkins Artifactory Plugin, like most of the JFrog clients, supports File Specs for downloading and uploading generic files.
The File Specs schema is described here. When creating a File Spec for downloading files, you have the option of using the "pattern" property, which can include wildcards. For example, the following spec downloads all the zip files from the my-local-repo repository into the local froggy directory:
{
"files": [
{
"pattern": "my-local-repo/*.zip",
"target": "froggy/"
}
]
}
Alternatively, you can use "aql" instead of "pattern". The following spec, provides the same result as the previous one:
{
"files": [
{
"aql": {
"items.find": {
"repo": "my-local-repo",
"$or": [
{
"$and": [
{
"path": {
"$match": "*"
},
"name": {
"$match": "*.zip"
}
}
]
}
]
}
},
"target": "froggy/"
}
]
}
The allowed AQL syntax inside File Specs does not include everything the Artifactory Query Language allows. For examples, you can't use the "include" or "sort" clauses. These limitations were put in place, to make the response structure known and constant.
Sorting however is still available with File Specs, regardless of whether you choose to use "pattern" or "aql". It is supported throw the "sortBy", "sortOrder", "limit" and "offset" File Spec properties.
For example, the following File Spec, will download only the 3 largest zip file files:
{
"files": [
{
"aql": {
"items.find": {
"repo": "my-local-repo",
"$or": [
{
"$and": [
{
"path": {
"$match": "*"
},
"name": {
"$match": "*.zip"
}
}
]
}
]
}
},
"sortBy": ["size"],
"sortOrder": "desc",
"limit": 3,
"target": "froggy/"
}
]
}
And you can do the same with "pattern", instead of "aql":
{
"files": [
{
"pattern": "my-local-repo/*.zip",
"sortBy": ["size"],
"sortOrder": "desc",
"limit": 3,
"target": "local/output/"
}
]
}
You can read more about File Specs here.
(After answering this question here, we also updated the File Specs documentation with these examples).
After a lot of testing and experimenting i found that there are many ways of solving my main problem (getting latest version of package) but each of way require some function which is available in paid version. Like sort() in AQL or [RELEASE] in REST API. But i found that i still can get JSON with a full list of files and its properties. I can also download each single file. This led me to solution with simple python script. I can't publish whole but only the core which should bu fairly obvious
import requests, argparse
from packaging import version
...
query="""
items.find({
"type" : "file",
"$and":[{
"repo" : {"$match" : \"""" + args.repository + """\"},
"path" : {"$match" : \"""" + args.path + """\"}
}]
}).include("name","repo","path","size","property.*")
"""
auth=(args.username,args.password)
def clearVersion(ver: str):
new = ''
for letter in ver:
if letter.isnumeric() or letter == ".":
new+=letter
return new
def lastestArtifact(response: requests):
response = response.json()
latestVer = "0.0.0"
currentItemIndex = 0
chosenItemIndex = 0
for results in response["results"]:
for prop in results['properties']:
if prop["key"] == "tag":
if version.parse(clearVersion(prop["value"])) > version.parse(clearVersion(latestVer)):
latestVer = prop["value"]
chosenItemIndex = currentItemIndex
currentItemIndex += 1
return response["results"][chosenItemIndex]
req = requests.post(url,data=query,auth=auth)
if args.verbose:
print(req.text)
latest = lastestArtifact(req)
...
I just want to point that THIS IS NOT permanent solution. We just didnt want to buy license yet only because of one single problem. But if there will be more of such problems then we definetly buy PRO subscription.

React, Webpacks and Babel: "You may need an appropriate loader to handle this file type." [duplicate]

I am trying to use Webpack with Babel to compile ES6 assets, but I am getting the following error message:
You may need an appropriate loader to handle this file type.
| import React from 'react';
| /*
| import { render } from 'react-dom'
Here is what my Webpack config looks like:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './index',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/dist/'
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/
}
]
}
}
Here is the middleware step that makes use of Webpack:
var webpack = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');
var config = require('./webpack.config');
var express = require('express');
var app = express();
var port = 3000;
var compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, {
noInfo: true,
publicPath: config.output.publicPath
}));
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
app.listen(port, function(err) {
console.log('Server started on http://localhost:%s', port);
});
All my index.js file is doing is importing react, but it seems like the 'babel-loader' is not working.
I am using 'babel-loader' 6.0.0.
You need to install the es2015 preset:
npm install babel-preset-es2015
and then configure babel-loader:
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015']
}
}
Make sure you have the es2015 babel preset installed.
An example package.json devDependencies is:
"devDependencies": {
"babel-core": "^6.0.20",
"babel-loader": "^6.0.1",
"babel-preset-es2015": "^6.0.15",
"babel-preset-react": "^6.0.15",
"babel-preset-stage-0": "^6.0.15",
"webpack": "^1.9.6",
"webpack-dev-middleware": "^1.2.0",
"webpack-hot-middleware": "^2.0.0"
},
Now configure babel-loader in your webpack config:
{ test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }
add a .babelrc file to the root of your project where the node modules are:
{
"presets": ["es2015", "stage-0", "react"]
}
More info:
babeljs.io - using babel with webpack
babeljs.io - docs on .babelrc
react-webpack-cookbook - configure react with webpack
a react-webpack-example repo
If you are using Webpack > 3 then you only need to install babel-preset-env, since this preset accounts for es2015, es2016 and es2017.
var path = require('path');
let webpack = require("webpack");
module.exports = {
entry: {
app: './app/App.js',
vendor: ["react","react-dom"]
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, '../public')
},
module: {
rules: [{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader?cacheDirectory=true',
}
}]
}
};
This picks up its configuration from my .babelrc file:
{
"presets": [
[
"env",
{
"targets": {
"browsers":["last 2 versions"],
"node":"current"
}
}
],["react"]
]
}
BABEL TEAM UPDATE:
We're super 😸 excited that you're trying to use ES2015 syntax, but instead of continuing yearly presets, the team recommends using babel-preset-env. By default, it has the same behavior as previous presets to compile ES2015+ to ES5
If you are using Babel version 7 you will need to run npm install #babel/preset-env and have "presets": ["#babel/preset-env"] in your .babelrc configuration.
This will compile all latest features to es5 transpiled code:
Prerequisites:
Webpack 4+
Babel 7+
Step-1:: npm install --save-dev #babel/preset-env
Step-2: In order to compile JSX code to es5 babel provides #babel/preset-react package to convert reactjsx extension file to native browser understandable code.
Step-3: npm install --save-dev #babel/preset-react
Step-4: create .babelrc file inside root path path of your project where webpack.config.js exists.
{
"presets": ["#babel/preset-env", "#babel/preset-react"]
}
Step-5: webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: path.resolve(__dirname, 'src/index.js'),
output: {
path: path.resolve(__dirname, 'output'),
filename: 'bundle.js'
},
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html",
filename: "./index.html"
})
]
}
In my case, I had such error since import path was wrong:
Wrong:
import Select from "react-select/src/Select"; // it was auto-generated by IDE ;)
Correct:
import Select from "react-select";
Due to updates and changes overtime, version compatibility start causing issues with configuration.
Your webpack.config.js should be like this you can also configure how ever you dim fit.
var path = require('path');
var webpack = require("webpack");
module.exports = {
entry: './src/js/app.js',
devtool: 'source-map',
mode: 'development',
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"]
},{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}]
},
output: {
path: path.resolve(__dirname, './src/vendor'),
filename: 'bundle.min.js'
}
};
Another Thing to notice it's the change of args, you should read babel documentation https://babeljs.io/docs/en/presets
.babelrc
{
"presets": ["#babel/preset-env", "#babel/preset-react"]
}
NB: you have to make sure you have the above #babel/preset-env & #babel/preset-react installed in your package.json dependencies
You probably forgot to add .js extension to your file.
Component -> Component.js
This makes me feel stupid, but I want to share for anyone that got frustrated like me: I used webpack.dev.js but didn't specify that as the config file! When running Webpack run with:
webpack --config webpack.dev.js
And it suddenly worked ;)
Just adding on another reason such error showed up in Angular.. was because I checked for html file in list of styles:
#Component({
selector: ...,
templateUrls: 'xyz.html',
stylesUrls: ['xyz.html'] // problem
})
Addressing wrong file type raises this error
As question doesn't specify if it was for angular, react, or react-native. I am posting this for react-native and it may be implied on others too. The reason was that it wasn't able to understand the syntax specified by loader. e.g. tsx, jsx. One solution I found in this article after lots of exploration. When we use external library that was using jsx and you configured your project with tsx, it won't understand jsx and will give you to add appropriate loader. So, you can fix that by following code in your app.json file.
"web": {
"build": {
"babel": {
"include": [
"name-of-my-shared-package-here"
]
}
}
}
By replacing name-of-my-shared-package-here with your package name that is causing the issue will solve this issue. You can check the package name in error that is causing this issue.
Outdated babel packages on Jan 3, 2023
Please install these list of packages for configuration with babel.
$ npm add -D #babel/core babel-loader #babel/preset-env #babel/preset-react
and add below code .babelrc file
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
]
}
I used #khizer webpack configuration in my application
Credit goes to This answer. As I have have been gone through the best answer of this solution and it tooks my 2-3 hours. I hope other don't waste same amount of time.
When using Typescript:
In my case I used the newer syntax of webpack v3.11 from their documentation page
I just copied the css and style loaders configuration form their website.
The commented out code (newer API) causes this error, see below.
module: {
loaders: [{
test: /\.ts$/,
loaders: ['ts-loader']
},
{
test: /\.css$/,
loaders: [
'style-loader',
'css-loader'
]
}
]
// ,
// rules: [{
// test: /\.css$/,
// use: [
// 'style-loader',
// 'css-loader'
// ]
// }]
}
The right way is to put this:
{
test: /\.css$/,
loaders: [
'style-loader',
'css-loader'
]
}
in the array of the loaders property.
This one throw me for a spin.
Angular 7, Webpack
I found this article so I want to give credit to the Article
https://www.edc4it.com/blog/web/helloworld-angular2.html
What the solution is:
//on your component file. use template as webpack will treat it as text
template: require('./process.component.html')
for karma to interpret it
npm install add html-loader --save-dev
{
test: /.html$/,
use: "html-loader"
},
Hope this helps somebody
Just add this code webpackmix.js
mix.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', [
require('tailwindcss'),
]).vue();

Travis CI - Builds are timing out

My .travis.yml
language: node_js
node_js:
- "0.12"
before_install:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
I have only added a few very simple tests so far (checking that class attributes exist).
I can see the tests are executed.
Then, the last few lines in the Travis output are this:
WARN [web-server]: 404: /css/style.min.css?1435068425.642
No output has been received in the last 10 minutes, this potentially indicates a stalled build or something wrong with the build itself.
The build has been terminated
If the tests are running, then the build and dependencies must have been installed already?
So why is the process not finishing once all tests are executed?
karma.config:
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: [
'jasmine',
'requirejs'
],
// list of files / patterns to load in the browser
files: [
{pattern: 'js/vendor/**/*.js', included: false},
{pattern: 'js/*.js', watched: true, included: false},
{pattern: 'test/**/*Spec.js', watched: true, included: false},
{pattern: 'css/**/*.css', included: false},
'test/test-main.js'
],
// list of files to exclude
exclude: [
'test/lib/**/*.js',
'js/vendor/**/test/*.js', //do not include the vendor tests
'js/_admin.js'
],
preprocessors: {
},
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Firefox'], //'Chrome', 'PhantomJS', 'PhantomJS_custom'
singleRun: false,
});//config.set
};//module.exports
test-main.js in folder test:
var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;
Object.keys(window.__karma__.files).forEach(function(file) {
if (TEST_REGEXP.test(file)) {
// Normalize paths to RequireJS module names.
allTestFiles.push(file);
}
//console.log('test files:', allTestFiles);
});
require.config({
baseUrl: '/base',
paths: {
'jquery': './js/vendor/jquery/jquery-2.1.4.min',
'jquery-ui': './js/vendor/jquery-ui-1.11.4.custom/jquery-ui.min',
'underscore': './js/vendor/underscore/underscore-min',
'backbone': './js/vendor/backbone/backbone-min',
'mustache': './js/vendor/mustache/mustache.min',
'domReady': './js/vendor/requirejs/plugins/domReady/domReady',
'text': './js/vendor/requirejs/plugins/text/text',
//------------------------------------
//custom requireJS application modules
'my': './js/my',
'my-CSS': './js/my-CSS'
},
shim: {
'underscore': {
exports: '_'
}
},
deps: allTestFiles,
callback: window.__karma__.start
});
The my-CSS module loads the css like this:
//custom requireJS module to hold the crowdUI class
define(["my"], function (my) { //prerequisites
'use strict';
//load the CSS definitions
document.head.appendChild(
my.createElement('link', {
attribute: {
id: 'my-CSS',
href: './css/style.min.css?' + crowdUI.TIMESTAMP,
rel: 'stylesheet',
type: 'text/css'
}
})
);
});
If the issue is just that your task requires more than 10 minutes during which it produces no output, the fix is simple: prepend your command with travis_wait.
For instance travis_wait myCommand instead of just myCommand.

Resources