Serving a modified asset-manifest.json in CRA using CRACO doesn't work - create-react-app

I have just created a new CRA app. In our organization we have a micro frontend framework which has certain requirements when it comes to the the asset file of each micro frontend app. CRA will by default, create a asset-manifest.json file.
https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/webpack.config.js#L656
Now I need to change this file to assets.json and make some structural changes as well. To achieve this I use CRACO and add the WebpackManifestPlugin.
const ManifestPlugin = require('webpack-manifest-plugin');
module.exports = {
webpack: {
plugins: {
// tried removing CRA definition for ManifestPlugin.
// It worked, but had no impact on my problem
// remove: ['ManifestPlugin'],
add: [
new ManifestPlugin({
fileName: 'assets.json',
generate: (seed, files, entrypoints) => {
const js = [],
css = [];
files.forEach((file) => {
if (file.path.endsWith('.js') && file.isInitial) {
js.push({ value: file.path, type: 'entry' });
}
if (file.path.endsWith('.css') && file.isInitial) {
css.push({ value: file.path, type: 'entry' });
}
});
return { js, css };
},
})
]
}
}
};
Whenever I build the application, my new assets.json file is generated as expected.
However, I can't get CRA, or webpack-dev-server I assume, to serve this file while I run my CRA app in development mode. It only resolves to the index.html file. I have looked through CRA source code and can't really find any relevant place where asset-manifest.json is mentioned.
So how do I get webpack-dev-server to serve my assets.json file?

You need to add the ManifestPlugin to webpack.plugins.remove array to receive only the configuration from WebpackManifestPlugin:
...
webpack: {
alias: {},
plugins: {
add: [
new WebpackManifestPlugin(webpackManifestConfig)
],
remove: [
"ManifestPlugin"
],
},
configure: (webpackConfig, { env, paths }) => { return webpackConfig; }
},
...

Related

Module parse failed: Unexpected token in Storybook when working with pdfjs-dist

I am working with a package that uses the pdfjs-dist package, and when trying to load the component that uses it in my Storybook, I get the following error
ERROR in ./node_modules/pdfjs-dist/build/pdf.js 2267:39
Module parse failed: Unexpected token (2267:39)
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
|
| async getXfa() {
> return this._transport._htmlForXfa?.children[this._pageIndex] || null;
| }
|
My guess, it is about handling XFA files, which are PDF files.
This is my main.js file in .storybook
const path = require('path');
module.exports = {
stories: ['../components/**/*.stories.js', '../components/**/*.stories.mdx'],
addons: [
'#storybook/addon-links',
'#storybook/addon-essentials',
'storybook-dark-mode',
'storybook-addon-next-router',
],
webpackFinal: async (config, { isServer }) => {
config.resolve.modules = [path.resolve(__dirname, '..'), 'node_modules'];
config.resolve.alias = {
...config.resolve.alias,
'#': path.resolve(__dirname, '../components'),
store: path.resolve(__dirname, '../utils/stores'),
dummy: path.resolve(__dirname, '../utils/dummy'),
};
if (!isServer) {
config.node = {
fs: 'empty',
};
}
return config;
},
};
pdfjs-dist: https://github.com/mozilla/pdf.js
react-pdf-viewer: https://github.com/react-pdf-viewer/react-pdf-viewer
The component works swimmingly in my development server, the issue is only in Storybook. Because of that issue, it is unable to even start the storybook server. If I remove the component that uses the package, storybook loads.
The error tells me to use proper webpack configs, but I just cannot figure that one out. This is what I tried, and it didn't work. (in webpackFInal: async () => { ... )
config.module.entry['pdf.worker'] = 'pdfjs-dist/build/pdf.worker.entry';
and
config.module.rules.push({
test: /pdf\.worker\.js$/,
type: 'asset/inline',
generator: {
dataUrl: (content) => content.toString(),
},
});
Found them here: https://github.com/mozilla/pdf.js/issues/14172

Vue CLI Service production build without version code?

I have a vue project and I use vue-cli-service build to build the project for production.
I noticed by default when I build the files, the resource name are having some kind of version code like
app.34fc5700.js
chunk-vendors.c7da5824.js
Is there a way to get rid of it?
I'm using vue.config.js, there's no webpack.conf.js in my project, and this is how it looks like:
module.exports = {
publicPath: process.env.VUE_APP_ROOT_PATH,
outputDir: process.env.VUE_APP_BUILD_DIR,
chainWebpack: config => {
config.resolve.symlinks(false);
config.plugin('html').init((Plugin, args) => {
const newArgs = {
...args[0],
};
newArgs.minify && (newArgs.minify.removeAttributeQuotes = false);
return new Plugin(newArgs);
});
},
css: {
loaderOptions: {
sass: {
additionalData: '#import "#/scss/_variables.scss";',
},
},
}
}
Looks like the option filenamehashing is something you need. Basically this option is enabled by default so you might need to turn it off:
// vue.config.js
module.exports = {
filenameHashing: false,
// ...
};

Storybook with craco - call a different verson of react-scripts

Storybook currently calls react-scripts. However, I've got some parts of the CRA config overriden with craco. It means my application is invoked with craco ..., rather than react-scripts ....
Is there a clean solution to have Storybook call craco instead?
The solution I came up with is this :
.storybook/main.js :
const path = require('path');
module.exports = {
stories: ['../src/**/*.stories.js'],
addons: [
'#storybook/preset-create-react-app',
'#storybook/addon-actions',
'#storybook/addon-links',
'#storybook/addon-viewport/register',
'#storybook/addon-knobs/register',
],
webpackFinal(config, { configType }) {
return {
...config,
resolve: {
alias: {
...config.resolve.alias,
'~': path.resolve(__dirname, '../src/'),
},
},
};
},
};
I was only using the alias feature in my craco file, so here I override webpack config from storybook and only add the alias parameter. For your case, you'll need to add your own config.
The #FR073N solution is good, but since the lasts versions, this throw an error.
One line was missing to fully override correctly the webpack config.
const path = require('path');
module.exports = {
stories: ['../src/**/*.stories.js'],
addons: [
'#storybook/preset-create-react-app',
'#storybook/addon-actions',
'#storybook/addon-links',
'#storybook/addon-viewport/register',
'#storybook/addon-knobs/register',
],
webpackFinal(config, { configType }) {
return {
...config,
resolve: {
...config.resolve, // <= HERE
alias: {
...config.resolve.alias,
'~': path.resolve(__dirname, '../src/'),
},
},
};
},
};
I've successfully used storybook-preset-craco with #storybook#6.3.5 and react-scripts#4.0.3 and #craco/craco#6.2.0 in a new CRA TypeScript project.

Programmatically bundling Nuxt.js application

I am newish to Nuxt world so I will try to describe what I need and what I was failing to do.
I am trying to programmatically build Nuxt application, bundle it and to mount it to a route
const { Nuxt, Builder } = require('nuxt');
const options = require('./nuxt.config.js');
const nuxt = new Nuxt(options);
try {
await new Builder(nuxt).build();
} catch(error) {
logger.error('Error building');
logger.log({ level: 'error', message: error });
}
So what I am interested in is programmatically controlling on how my Nuxt application will be bundled. That should not be an issue since my app is aware of their environment during build time.
So for production environment I would like to load everything bundled and minified/uglified and what else... So if possible I would like to load all html stuff + 1 JS file + 1 css file.
my example config file is
module.exports = {
build: {
// I should put something here
}
},
srcDir: 'app/view/',
modules: [
'#nuxtjs/axios',
'#nuxtjs/proxy'
],
head: {
script: [
{ rel: 'preload', src: `https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v3.2&appId=${facebookAppId}&autoLogAppEvents=1` }
],
meta: [
]
},
axios: {
port: 3010
},
router: {
middleware: [ /*my middlewares*/ ]
}
};
So the question is how can I control build in order to achieve what I want? Bonus point for me would be if I managed to load scripts from head.script and merge it to bundle.js file

Vue Cli 3 build custom directory for different type of files

I am new in using vue to build web app.
By default, use npm run build, it will build the following structure:
But I hope to build as follow:
Then, how can I write the vue.config.js as output like what I want?
Using this GitHub issue as an example, you should be able to achieve this by adding something like this to your configuration...
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module.rule('images').use('url-loader')
.loader('file-loader') // replaces the url-loader
.tap(options => Object.assign(options, {
name: 'images/register/[name].[hash:8].[ext]'
}))
config.module.rule('svg').use('file-loader')
.tap(options => Object.assign(options, {
name: 'images/register/[name].[hash:8].[ext]'
}))
},
css: {
extract: {
filename: 'css/register/[name].[hash:8].css',
chunkFilename: 'css/register/[name].[hash:8].css'
}
},
configureWebpack: {
output: {
filename: 'js/register/[name].[hash:8].js',
chunkFilename: 'js/register/[name].[hash:8].js'
}
}
}
See https://cli.vuejs.org/config/#vue-config-js for more information and examples.