Programmatically bundling Nuxt.js application - vue.js

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

Related

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

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; }
},
...

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

Custom Local Font is not working after deploying to the server in VUE

I have worked with Vue CLI 3 project and used a custom local fonts in this project. These custom fonts are working fine on local but after building to the server it is not working.
Is this something related to my Vue.config.js file?
This is my vue.config.js file.
module.exports = {
publicPath: '/', // Base directory for dev
configureWebpack: {
module: {
rules: [{
test: /\.(ttf|otf|eot|woff|woff2)$/,
use: {
loader: "file-loader",
options: {
name: "assets/fonts/[name].[ext]",
},
},
}]
}
}
}

How to conditionally apply different webpack loaders, depending on the source entry?

I have a React app built with webpack, I want to ignore css module loading on some conditions.
I have 2 configurations for webpack:
I need to load all css modules for the browser build (not a problem for now)
I need to load css modules for the server only when it's not the Server Side Rendering (SSR) app tree
Here is some pseudo code for illustration (btw the app is an OSS):
// webpack.browser.js (standard build)
{
entry: './client.jsx',
module: { loaders: [ { test: /\.scss$/, loaders: ['style', 'css', 'sass'] } ] },
}
// client.jsx
import App from './src/App.jsx';
// ...App includes styles
// webpack.server.js
{
entry: './server.js',
module: { loaders: [
{
test: /\.scss$/,
loaders: [
// may be conditionally load scss depending on which express middleware the app is builded
]
}
] },
}
// server.js
// ...
import App from './src/App.jsx';
import LandingPage from './src/LandingPage.jsx';
app.use('/app', function ssrMiddleware(req, res) {
// How to not load scss modules ?
const html = ReactDOMServer.renderToStaticMarkup(React.createElement(App));
res.send(html);
});
app.use('/', function websiteMiddleware(req, res) {
// How to load scss modules ?
const html = ReactDOMServer.renderToStaticMarkup(React.createElement(LandingPage));
res.send(html);
});
I'm aware about pithing loader, but I don't understand how it can solves my case.

Why are my js files being loaded as `index.html` instead of the actual js files created by webpack?

I'm creating a simple build from webpack, using typescript, jade, and stylus. When the final index.html file is spit out, however, it seems to think the js files are just the index.html file and not the actual js files bundled up by webpack and dynamically inserted at the bottom of the html body.
My project directory structure looks like this:
- dist (compiled/transpiled files)
- server
- dependencies
- index.js
- app.js
- app.[hash].js
- polyfills.[hash].js
- node_modules
- src
- server
- dependencies
- index.ts
- app.ts
- client (ng2 ts files)
- index.jade
This is my webpack build:
'use strict';
const webpack = require('webpack');
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const WebpackShellPlugin = require('webpack-shell-plugin');
const rootDir = __dirname;
/**
* Resolve paths so that we don't have to use relative paths when importing dependencies.
* Very helpful when scaling an application and changing the location of a file that my require another file
* in the same directory as the one it used to be in
*/
const pathResolves = [path.resolve(rootDir, 'src'), path.resolve(rootDir, 'node_modules')];
console.log('path', path.resolve(rootDir, 'src/server'));
module.exports = {
entry: {
'app': path.resolve(rootDir, 'src/client/main.ts'),
'polyfills': [
'core-js/es6',
'core-js/es7/reflect',
'zone.js/dist/zone'
]
},
output: {
path: path.resolve(rootDir, 'dist'),
filename: '[name].[hash].js'
},
module: {
rules: [
{
test: /\.component.ts$/,
use: [
{
loader: 'angular2-template-loader'
},
{
loader: 'ts-loader',
options: {
configFileName: path.resolve(rootDir, 'tsconfig.client.json')
}
}],
include: [path.resolve(rootDir, 'src/client')]
},
{
test: /\.ts$/,
use: [
{
loader: 'ts-loader',
options: {
configFileName: path.resolve(rootDir, 'tsconfig.client.json')
}
}
],
exclude: /\.component.ts$/
},
{
test: /\.jade$/,
use: ['pug-ng-html-loader']
},
{
test: /\.styl$/,
use: [
{ loader: 'raw-loader' },
{ loader: 'stylus-loader' }
]
}
]
},
resolve: {
extensions: ['.js', '.ts', '.jade', '.styl'],
modules: pathResolves
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'polyfills'
}),
new HTMLWebpackPlugin({
template: path.resolve(rootDir, 'dist/index.html')
}),
/**
* Define any environment variables for client
*/
new webpack.DefinePlugin({
APP_ENV: JSON.stringify(process.env.APP_ENVIRONMENT || 'development')
}),
/**
* This plugin is required because webpack 2.0 has some issues compiling angular 2.
* The angular CLI team implemented this quick regexp fix to get around compilation errors
*/
new webpack.ContextReplacementPlugin(
/angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
'./'
)
]
};
And finally, this is the src/server/app.ts file that serves up index.html:
import * as express from 'express';
import * as fs from 'fs';
import * as morgan from 'morgan';
import {
Config
}
from './dependencies/config';
export
function app(Container) {
const app = express();
const config: Config = Container.get(Config);
if (config.log.dev) {
app.use(morgan('combined'));
}
app.get('/', (req: express.Request, res: express.Response) => {
const indexPath: string = `dist/index.html`;
const encodeType: string = `utf-8`;
const html = fs.readFile(indexPath, encodeType, (err: Error, result: string) => {
if (err) {
return res.status(500).json(err);
}
return res.send(result);
});
});
return app;
}
The browser console shows the following 404 error messages (they're red in the browser console) when i go to localhost:3000:
GET http://localhost:3000/polyfills.9dcbd04127bb957ccf5e.js
GET http://localhost:3000/app.9dcbd04127bb957ccf5e.js
I know it's supposed to be getting the js files from dist/[file].[hash].js, but can't seem to make it work with webpack. Also, I should note that I set NODE_PATH to ./ in my gulp nodemon config. Any ideas why this isn't working?
Figured it out on my own. Forgot to add app.use(express.static('dist')) middleware to the app.ts file.