Hi!
I'm trying to use a lib that ships untranspiled to NPM, and thus needs transpiling locally in the Razzle-project. I modified my razzle-config to include the module for transpilation in the js loader, and that seems to work fine for the client build as it no longer errors. However, I get the "unexpected token import"-error in what I assume is the server build.
Any ideas about this? I guess the problem is that I'd somehow need the module to be transpiled for the server as well?
Thanks in advance!
Managed to solve it. For future reference:
Turns out webpack-node-externals
is applied and used during SSR, meaning no modules from node_modules
are included for bundling and thus transpiling. I solved it by doing something along these lines in my razzle.config.js
:
config.externals = target === 'node' ? [
nodeExternals({
whitelist: [
dev ? 'webpack/hot/poll?300' : null,
/\.(eot|woff|woff2|ttf|otf)$/,
/\.(svg|png|jpg|jpeg|gif|ico)$/,
/\.(mp4|mp3|ogg|swf|webp)$/,
/\.(css|scss|sass|sss|less)$/,
/^my-untranspiled-package/
].filter(Boolean),
}),
] : [];
...where a majority of that code is copied right from createConfig.js
in this repo.
@zth thank you!!
@zth how did you get it to work on the client side in the first place? could you share your config?
Ok, I figured it out. You need to extend the includes of the babel-loader
. Also you have to set the babelOptions
explicitly unless they are specified in a .babelrc
inside the untranspiled package, having a /babelrc
in your apps package is not enough.
Here's a complete example config:
'use strict';
const nodeExternals = require('webpack-node-externals');
const fs = require('fs');
module.exports = {
modifyBabelOptions() {
return {
presets: ['razzle/babel'],
plugins: ['transform-flow-strip-types'],
};
},
modify(config, { target, dev }, webpack) {
// package un-transpiled packages
const babelRuleIndex = config.module.rules.findIndex(
(rule) => rule.use && rule.use[0].loader && rule.use[0].loader.includes('babel-loader')
);
config.module.rules[babelRuleIndex] = Object.assign(config.module.rules[babelRuleIndex], {
include: [
...config.module.rules[babelRuleIndex].include,
fs.realpathSync('./node_modules/untranspiled-package')
],
});
config.externals =
target === 'node'
? [
nodeExternals({
whitelist: [
dev ? 'webpack/hot/poll?300' : null,
/\.(eot|woff|woff2|ttf|otf)$/,
/\.(svg|png|jpg|jpeg|gif|ico)$/,
/\.(mp4|mp3|ogg|swf|webp)$/,
/\.(css|scss|sass|sss|less)$/,
/^untranspiled-package/,
].filter(Boolean),
}),
]
: [];
// return
return config;
},
};
I managed to do the same trick as @MrLoh also for Typescript ts-loader. Check allowedPackages, you can insert your package name there. I also took into account an idea that it seems that it is enough for current version of Razzle to be without custom config.externals, but you might be interested also in original @MrLoh solution (see about config.externals deletion: https://github.com/jaredpalmer/razzle/issues/842#issuecomment-475722036)
const allowedPackages = ['my-component']
const allowedPackagePaths = allowedPackages.map(packageName =>
fs.realpathSync('./node_modules/' + packageName)
)
const tsRuleIndex = config.module.rules.findIndex(
rule =>
rule.use && rule.use[0].loader && rule.use[0].loader.includes('ts-loader')
)
if (tsRuleIndex === -1) {
throw Error(
'This component assumes that you are using ts-loader. If you are not using it, then you might need to check and test code for how would it work with other loaders'
)
}
config.module.rules[tsRuleIndex] = {
...config.module.rules[tsRuleIndex],
include: [
...config.module.rules[tsRuleIndex].include,
...allowedPackagePaths,
],
}
delete config.externals
This worked with me. My question is, The libraries are being duplicated in the client and server bundle. Any way to chunk this common this into a new file using razzle.config.js ?
Most helpful comment
Ok, I figured it out. You need to extend the includes of the
babel-loader
. Also you have to set thebabelOptions
explicitly unless they are specified in a.babelrc
inside the untranspiled package, having a/babelrc
in your apps package is not enough.Here's a complete example config: