Unexpected token < SystemJS Production build - angularjs

I am using AngularJS writen in typescript and SystemJS module builder.
My app's main file (app.ts) is located inside Scripts/App.
SytemJS production configuration from gulpfile.js:
gulp.task("deploy", ["ts", "vendorjs", "app-css"], function (done) {
return systemBuild("./Scripts/App/app", "./dist/js/main_" + build + ".min.js");
});
function systemBuild(sourcepath, targetPath, cb) {
var builder = new Builder();
// Collection bundling
builder.config({
defaultJSExtensions: true,
map: {
"ts": "node_modules/plugin-typescript/lib/plugin.js"
},
baseURL: "./Scripts",
transpiler: "ts",
typescriptOptions: {
module: "system",
target: "es5",
sourceMap: true,
inlineSourceMap: true,
inlineSources: true,
resolveTypings: true,
emitDecoratorMetadata: true,
noImplicitAny: true,
typeCheck: true, // also accepts "strict"
tsconfig: true // also accepts a path
},
packages: {
"app": {
defaultExtension: "ts"
}
}
});
return builder.buildStatic(sourcepath, targetPath, {
minify: true,
mangle: true,
sourceMaps: false,
sourceMapContents: false,
globalDefs: { DEBUG: false }
});
}
After running gulp default, I am getting 'Uncaught SyntaxError: Unexpected token <' error. Could anybody tell me what I am doing wrong?

Related

Storybook couldn't resolve fs

I am setting up a Storybook with RemixJS. I got the following error when trying to import a component
ERROR in ./node_modules/#remix-run/node/errors.js
Module not found: Error: Can't resolve 'fs' in '/Users/ht/Desktop/a/node_modules/#remix-run/node'
ERROR in ./node_modules/#remix-run/node/node_modules/source-map/lib/read-wasm.js
Module not found: Error: Can't resolve 'fs' in '/Users/ht/Desktop/a/node_modules/#remix-run/node/node_modules/source-map/lib'
ERROR in ./node_modules/#remix-run/node/sessions/fileStorage.js
Module not found: Error: Can't resolve 'fs' in '/Users/ht/Desktop/a/node_modules/#remix-run/node/sessions'
ERROR in ./node_modules/busboy/lib/main.js
Module not found: Error: Can't resolve 'fs' in '/Users/ht/Desktop/a/node_modules/busboy/lib'
ERROR in ./node_modules/#remix-run/node/errors.js
Module not found: Error: Can't resolve 'fs/promises' in '/Users/ht/Desktop/a/node_modules/#remix-run/node'
ERROR in ./node_modules/#remix-run/node/upload/fileUploadHandler.js 124:15
Module parse failed: Unexpected token (124:15)
You may need an appropriate loader to handle this file type, currently, no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| }
| class NodeOnDiskFile {
> lastModified = 0;
| webkitRelativePath = "";
|
ERROR in ./node_modules/#remix-run/node/formData.js 53:73
Module parse failed: Unexpected token (53:73)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| get(name) {
| let arr = this._fields[name];
> return (arr === null || arr === void 0 ? void 0 : arr.slice(-1)[0]) ?? null;
| }
|
I got the suggestion that I should add this to the web pack
{
resolve: {
fallback: {
fs: false
}
}
}
How could I do it with a storybook? I use storybook version 6.4.19
I added this to .storybook/main.js but without success
webpackFinal: async (config, { configType }) => {
config.node = {
...config.node,
fs: 'empty'
};
return config;
},
Thank you
Depending on the webpack version you are using to build your Storybook you need to add fs, stream and other Node core module used by Remix packages.
As a rule of thumb you can use the list from Webpack documentation on resolve.fallback here.
If you are using Stroybook with Webpack 4 the config should look like :
module.exports = {
// Storybook config
webpackFinal: async (config, { configType }) => {
config.node = {
...config.node,
fs: "empty",
assert: "empty",
buffer: "empty",
console: "empty",
constants: "empty",
crypto: "empty",
domain: "empty",
events: "empty",
http: "empty",
https: "empty",
os: "empty",
path: "empty",
punycode: "empty",
process: "empty",
querystring: "empty",
stream: "empty",
string_decoder: "empty",
sys: "empty",
timers: "empty",
tty: "empty",
url: "empty",
util: "empty",
vm: "empty",
zlib: "empty",
};
return config;
},
};
Or with Webpack 5
module.exports = {
// Storybook config
webpackFinal: async (config, { configType }) => {
config.resolve.fallback = {
fs: false,
assert: false,
buffer: false,
console: false,
constants: false,
crypto: false,
domain: false,
events: false,
http: false,
https: false,
os: false,
path: false,
punycode: false,
process: false,
querystring: false,
stream: false,
string_decoder: false,
sys: false,
timers: false,
tty: false,
url: false,
util: false,
vm: false,
zlib: false,
};
return config;
},
};
Upgrade storybook to use webpack 5
https://gist.github.com/shilman/8856ea1786dcd247139b47b270912324
Update .storybook/main.js
module.exports = {
stories: ["../.slicemachine/assets/**/*.stories.#(js|jsx|ts|tsx)"],
addons: [
"#storybook/addon-links",
"#storybook/addon-essentials",
"#storybook/addon-interactions",
],
framework: "#storybook/react",
core: {
builder: "webpack5",
},
webpackFinal: async (config, { configType }) => {
config.resolve = {
...config.resolve,
fallback: {
...(config.resolve || {}).fallback,
fs: false,
stream: false,
os: false,
},
}
// Return the altered config
return config
},
}

Unit Testing Hybrid Angular Js and Angular 8 Application

I'm working on a angular js and angular 8 hybrid application. The new components created in angular are downgraded to be used in angular js. Code snippet of module is shown below:
#NgModule({
// Declaration and Imports
providers:[
ServiceName,
// Other Services
],
entryComponents: [
ComponentName,
// Other components to be used in angular js
]
})
export class FeatureModule{
}
declare var angular: angular.IAngularStatic
angular.module('app')
.directive('cmpName', downgradeComponent({component: ComponentName }) as angular.IDirectiveFactory)
.factory('serviceName', downgradeInjectable(ServiceName));
In app.module.ts file, there is following code.
// Usual Stuff
export class AppModule {
constructor(
private upgrade: UpgradeModule,
) {
}
ngDoBootstrap() {
this.upgrade.bootstrap(document.body, ['app'], { strictDi: true });
}
}
Nothing has been updated in component spec file generated by angular cli.
In tsconfig.spec.json,
{
"extends": "../tsconfig.json",
"compilerOptions": {
"baseUrl": "./",
"outDir": "../out-tsc/spec",
"types": ["jasmine", "node", "angular"]
},
"files": ["test.ts", "polyfills.ts"],
"include": ["**/*.spec.ts", "**/*.d.ts"]
}
karma.conf.js looks like below.
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '#angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../coverage/ProjectFolder'),
reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};
Now, if I run npm run test or ng test command to run test suite, I'm getting following error.
An error was thrown in afterAll Uncaught ReferenceError: angular is not defined ReferenceError: angular is not defined at Module../..path-to-module-file/feature.module.ts.
How can I resolve this issue? Do I have to mock angular variable declared in the module file. Any help is appreciated?
I don't know too much of the nitty gritty details, but I run a hybrid application with Webpack and Karma. I downgrade all my components so they can be used in AngularJS, just like you.
The difference is that I have a file called vendor.ts that contains AngularJS. I bet you do too, since you only talk about the tests failing, not the product being broken. I have an entry in my Karma config file:
files: [
{ pattern: "node_modules/babel-polyfill/dist/polyfill.js", watched: false },
{ pattern: "node_modules/intl/locale-data/jsonp/en-GB.js", watched: false },
{ pattern: "node_modules/intl/locale-data/jsonp/fr-FR.js", watched: false },
{ pattern: "static/polyfills.ts", watched: false },
{ pattern: "static/vendor.ts", watched: false },
{ pattern: "node_modules/zone.js/dist/long-stack-trace-zone.js", watched: false },
{ pattern: "node_modules/zone.js/dist/proxy.js", watched: false },
{ pattern: "node_modules/zone.js/dist/sync-test.js", watched: false },
{ pattern: "node_modules/zone.js/dist/jasmine-patch.js", watched: false },
{ pattern: "node_modules/zone.js/dist/async-test.js", watched: false },
{ pattern: "node_modules/zone.js/dist/fake-async-test.js", watched: false },
{ pattern: "node_modules/angular-mocks/angular-mocks.js", watched: false },
{ pattern: "static/main.ts", watched: false },
{ pattern: "static/main.test.ts", watched: false },
],
This tells Karma which files to watch and serve in the browser. I think that means that after Webpack compiled these files, Karma-Webpack can find the compiled files and serve them.

React application caching

I am new to React. I have a React application which recently pushed to Production. There were some frontend fixes and again pushed to production. But it is showing the same page after new build. It is taking from cache. But if i remove cache, it is working.
Using react boilerplate (https://github.com/react-boilerplate/react-boilerplate)
I tried searching for Service worker and res.header(cache-control). But nothing seems to be worked.
Below is my webpack prod file
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackPwaManifest = require('webpack-pwa-manifest');
const OfflinePlugin = require('offline-plugin');
const { HashedModuleIdsPlugin } = require('webpack');
const webpack = require('webpack');
const S3Plugin = require('webpack-s3-plugin');
// const TerserPlugin = require('terser-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const config = require('../../app/config');
module.exports = require('./webpack.base.babel')({
mode: 'production',
// In production, we skip all hot-reloading stuff
entry: [
require.resolve('react-app-polyfill/ie11'),
path.join(process.cwd(), 'app/app.js'),
],
// Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets
output: {
filename: '[name].[chunkhash].js',
chunkFilename: '[name].[chunkhash].chunk.js',
},
// optimization: {
// minimize: true,
// minimizer: [
// new TerserPlugin({
// terserOptions: {
// warnings: false,
// compress: {
// comparisons: false,
// },
// parse: {},
// mangle: true,
// output: {
// comments: false,
// ascii_only: true,
// },
// },
// parallel: true,
// cache: true,
// sourceMap: true,
// }),
// ],
// nodeEnv: 'production',
// sideEffects: true,
// concatenateModules: true,
// splitChunks: {
// chunks: 'all',
// minSize: 30000,
// minChunks: 1,
// maxAsyncRequests: 5,
// maxInitialRequests: 3,
// name: true,
// cacheGroups: {
// commons: {
// test: /[\\/]node_modules[\\/]/,
// name: 'vendor',
// chunks: 'all',
// },
// main: {
// chunks: 'all',
// minChunks: 2,
// reuseExistingChunk: true,
// enforce: true,
// },
// },
// },
// runtimeChunk: true,
// },
plugins: [
// Minify and optimize the index.html
new HtmlWebpackPlugin({
template: 'app/index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
inject: true,
}),
new S3Plugin({
exclude: /.*\.html$/,
s3Options: {
accessKeyId: config.aws.s3.aws_access_key_id,
secretAccessKey: config.aws.s3.aws_secret_access_key,
region: 'us-west-2',
},
s3UploadOptions: {
Bucket: config.aws.s3.bucket,
},
}),
// Put it in the end to capture all the HtmlWebpackPlugin's
// assets manipulations and do leak its manipulations to HtmlWebpackPlugin
new OfflinePlugin({
relativePaths: false,
publicPath: '/',
appShell: '/',
// No need to cache .htaccess. See http://mxs.is/googmp,
// this is applied before any match in `caches` section
excludes: ['.htaccess'],
caches: {
main: [':rest:'],
// All chunks marked as `additional`, loaded after main section
// and do not prevent SW to install. Change to `optional` if
// do not want them to be preloaded at all (cached only when first loaded)
additional: ['*.chunk.js'],
},
// Removes warning for about `additional` section usage
safeToUseOptionalCaches: true,
AppCache: false,
ServiceWorker: {
events: true,
publicPath: '/sw.js',
navigateFallbackURL: '/',
prefetchRequest: {},
},
// Hack
// This is to skip the warning that OfflinePlugin throws if sw registration is not done
__tests: {
ignoreRuntime: true,
},
}),
new CompressionPlugin({
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8,
}),
new WebpackPwaManifest({
name: 'React Boilerplate',
short_name: 'React BP',
description: 'My React Boilerplate-based project!',
background_color: '#fafafa',
theme_color: '#b1624d',
inject: true,
ios: true,
icons: [
{
src: path.resolve('app/images/icon-512x512.png'),
sizes: [72, 96, 128, 144, 192, 384, 512],
},
{
src: path.resolve('app/images/icon-512x512.png'),
sizes: [120, 152, 167, 180],
ios: true,
},
],
}),
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en/),
new HashedModuleIdsPlugin({
hashFunction: 'sha256',
hashDigest: 'hex',
hashDigestLength: 20,
}),
],
performance: {
assetFilter: assetFilename =>
!/(\.map$)|(^(main\.|favicon\.))/.test(assetFilename),
},
});```
Use webpack and use hashing (and append it to file names) to generate the files.
Hence whenever you rebuild the app and deploy it on production those hashed files wont be present in the cache and you wont have the cache problem anymore.
You can disable caching if you don't want it but I guess here you wanted to refresh the cache on new deploys, pls try below
app/app.js - at the end of file
if (process.env.NODE_ENV === 'production') {
require('offline-plugin/runtime').install(); // eslint-disable-line global-require
}
replace with
if (process.env.NODE_ENV === 'production') {
const runtime = require('offline-plugin/runtime'); // eslint-disable-line global-require
runtime.install({
onUpdating: () => {
console.log('SW Event:', 'onUpdating');
},
onUpdateReady: () => {
console.log('SW Event:', 'onUpdateReady');
// Tells to new SW to take control immediately
runtime.applyUpdate();
},
onUpdated: () => {
console.log('SW Event:', 'onUpdated');
// Reload the webpage to load into the new version
window.location.reload();
},
onUpdateFailed: () => {
console.log('SW Event:', 'onUpdateFailed');
},
});
}
internals/webpack/webpack.prod.babel.js
add line 90, under new OfflinePlugin({
ServiceWorker: {
events: true,
},

Updating create-react-app proxy settings from 1.x to 2.x

I've picked up a legacy project, and have been asked to update the create-react-app package from 1.0.3 to the latest.
The problem is, the new proxy settings aren't working; requests that were previously going to my/resource.do are just returning index.html
As suggested in the docs (https://facebook.github.io/create-react-app/docs/proxying-api-requests-in-development#configuring-the-proxy-manually), I took the 'proxy' object in package.json and converted it to instructions in a file called setupProxy.js. The new js file is definitely being read; I just can't get it to work.
Can anyone see where the mistake is here? This is exactly as specified in the docs, but for some reason requests that worked before are now failing.
Any help greatly appreciated
Before (in package.json)
"proxy": {
"/api": {
"target": "http://localhost:9000"
},
"/some/thing": {
"target": "https://example.org:8452/",
"secure": false,
"changeOrigin": true
},
"/some": {
"target": "https://example.org:7324",
"secure": false,
"changeOrigin": true
},
"/.*": {
"target": "https://example.org:8452/",
"secure": false,
"changeOrigin": true
}
}
After (in setupProxy.js):
const proxy = require('http-proxy-middleware')
module.exports = function(app) {
app.use('/api', proxy({ target: 'http://localhost:9000/' }))
app.use('/some/thing', proxy(
{
target: 'https://example.org:8452/',
secure: false,
changeOrigin: true,
logLevel: 'debug'
}
))
app.use('/some', proxy(
{
target: 'https://example.org:7324/',
secure: false,
changeOrigin: true,
logLevel: 'debug'
}
))
app.use(proxy('/.*',
{
target: 'example.org:8452/',
secure: false,
changeOrigin: true,
logLevel: 'debug'
}
))
}

Webpack config for Code splitting not working for production build

Building a ReactJS application with Webpack. Recently interested in using code splitting to reduce app size.
I've tried implementing a custom HOC that wrapped System.import():
/* async/index.tsx */
... at a very high level looked like...
class Async extends React ... {
componentWillMount() {
this.props.load.then(c => {
this.component = c;
this.setState({loaded:true});
}
}
render() {
return this.component ? <this.component.default {...this.props} /> : <span />;
}
}
/* async/foo/index.tsx */
import Async from 'async';
const Foo = (props) => (
<Async
{...props}
load={System.import('async/foo/body')}
/>);
class Foo ... {
...
render = () => <Foo myProp={'bar'} />;
}
Currently I'm trying react-loadable (https://github.com/thejameskyle/react-loadable), a package that does essentially the same thing but with some extra bells n whistles.
Problem
Both methods work fine locally, but do not work when deployed. Webpack configurations are derived from React-Starter-App, from early March 2017. My gut tells me that the webpack config is the source of the problem, but I'm not sure how to debug this.
Dev Config (works)
/* relevant configs */
module.exports = {
entry: [
require.resolve('react-dev-utils/webpackHotDevClient'),
require.resolve('./polyfills'),
paths.appIndexJs
],
output: {
path: paths.appBuild,
pathinfo: true,
filename: 'static/js/bundle.js',
publicPath: publicPath
},
...
plugins: [
new ExtractTextPlugin({filename: 'style.css', allChunks: true}),
new InterpolateHtmlPlugin(env.raw),
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
}),
new BundleAnalyzerPlugin(),
new webpack.DefinePlugin(env.stringified),
new webpack.HotModuleReplacementPlugin(),
new CaseSensitivePathsPlugin(),
new webpack.LoaderOptionsPlugin({
debug: true
}),
new WatchMissingNodeModulesPlugin(paths.appNodeModules)
]
}
Staging Config (not working)
module.exports = {
bail: true,
devtool: 'source-map',
entry: [
require.resolve('./polyfills'),
paths.appIndexJs
],
output: {
path: paths.appBuildStaging,
filename: 'static/js/[name].[chunkhash:8].js',
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
publicPath: publicPath,
},
resolve: {
modules: ['node_modules', paths.appNodeModules].concat(paths.nodePaths).concat(paths.appSrc),
extensions: ['.ts', '.tsx', '.scss', '.js', '.json', '.jsx']
},
...
plugins: [
new InterpolateHtmlPlugin(env.raw),
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
// this assumes your vendor imports exist in the node_modules directory
return module.context && module.context.indexOf('node_modules') !== -1;
}
}),
//CommonChunksPlugin will now extract all the common modules from vendor and main bundles
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest' //But since there are no more common modules between them we end up with just the runtime code included in the manifest file
}),
new BundleAnalyzerPlugin(),
new webpack.DefinePlugin(env.stringified),
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true, //. React doesn't support IE8
warnings: false,
drop_console: false,
},
mangle: {
screw_ie8: true,
},
output: {
comments: false,
screw_ie8: true,
},
sourceMap: true,
}),
new ExtractTextPlugin({
filename: cssFilename,
}),
new ManifestPlugin({
fileName: 'asset-manifest.json',
}),
]
}
Errors:
react-loadable swallows all errors (palm + face) so I'm not able to provide useful errors from that code.
My custom component would throw an error in the bootstrap loader bootstrap 6a12c6c…:54 Uncaught (in promise) TypeError: Cannot read property 'call' of undefined
In the network traffic for my custom HOC, the extra bundle is not loaded.
In the network traffic for react-loadable, the bundle is loaded, but it is never processed.
So after all this time, after upgrading Typescript and Webpack, it turns out that using the CommonsChunk plugin was screwing it up somehow.
Have not yet investigated why, but commenting out the following worked:
// new webpack.optimize.CommonsChunkPlugin({
// name: 'vendor',
// minChunks: function (module) {
// return module.context && module.context.indexOf('node_modules') !== -1;
// }
// }),

Resources