getting conditionNames required warning, but my config has conditionNames property in webpack config
elirov opened this issue · 8 comments
$ yarn watch
yarn run v1.23.0-20220130.1630
WARNING: You should add "svelte" to the "resolve.conditionNames" array in your webpack config. See https://github.com/sveltejs/svelte-loader#resolveconditionnames for more information
webpack config file:
config.resolve = {
fallback: { assert: false },
extensions: ['.cjs', '.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.css', '.scss', '.svelte'],
modules: ['src', 'lib', 'node_modules', 'tmpls'],
alias: {
vendor: __dirname + '/lib/vendor',
jquery: __dirname + '/lib/vendor-adapters/jquery-global-adapter',
jqueryNonGlobal: __dirname + '/node_modules/jquery',
moment: __dirname + '/lib/vendor-adapters/moment-global-adapter',
momentNonGlobal: __dirname + '/node_modules/moment',
xdoc: __dirname + '/src/xdoc',
client: __dirname + '/src/client',
node_modules: 'node_modules',
test: __dirname + '/src/test',
svelte: __dirname + '/node_modules/svelte',
src: __dirname + '/src',
tmpls: __dirname + '/tmpls',
},
conditionNames: ['svelte'],
};Any places I should check? Is the warning looking at the value of the property? Or is it trying to parse the config file itself?
Could you post the complete config file (including where/how the export of it happens; you can redact any sensitive strings)? Check happens here and should find your settings, so that's strange
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const fs = require('fs');
const path = require('path');
const { merge } = require('webpack-merge');
const crypto = require('crypto');
const uuidv4 = require('uuid/v4');
const FORM_KEY = 'f0';
const XDOC_CONTAINER_ID = 'XDocContainer-' + FORM_KEY;
const argv = require('yargs')(process.argv.slice(2)).argv;
const { processNestedHtmlFactory, addTemplateAliases } = require('./webpack-utils');
const buildStaticFields = require('./build-utils/xdoc-static-field-processor');
const buildDynamicFields = require('./build-utils/xdoc-static-to-dynamic-field-converter');
const { pipe } = require('lodash/fp');
const sveltePreprocess = require('svelte-preprocess');
const ROOT = path.resolve(__dirname);
const rootPath = path.join.bind(path, ROOT);
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
const smp = new SpeedMeasurePlugin();
const getTmplConfig = async (env, tmplSettings) => {
const tmplName = env.tmpl;
let tmplDefinedSettings;
try {
//tmplDefinedSettings = require(rootPath(`/tmpls/${tmplName}/xdoc-platform-settings.mjs`)).default;
tmplDefinedSettings = await import(rootPath(`/tmpls/${tmplName}/xdoc-platform-settings.mjs`));
} catch (err) {
console.log(`${tmplName} needs to provide tmpls/${tmplName}/xdoc-platform-settings.mjs`, err);
throw err;
}
let fieldMapPath;
if (fs.existsSync(`${__dirname}/tmpls/${tmplName}/fieldmap/fieldmap.js`)) {
fieldMapPath = `tmpls/${tmplName}/fieldmap/fieldmap.js`;
} else {
fieldMapPath = `tmpls/${tmplName}/fieldMap.json`;
}
let fieldConverter;
if (tmplDefinedSettings.build?.convertFieldsToDynamic) {
console.log(`converting tmpls/${tmplName}/fieldMap.json static fields to dynamic fields`);
fieldConverter = buildDynamicFields;
} else {
console.log(`NOT converting static fields defined in tmpls/${tmplName}/fieldMap.json`);
fieldConverter = buildStaticFields;
}
const config = {
infrastructureLogging: {
level: 'warn',
},
entry: {},
target: 'web',
module: {
rules: [
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: {
esModule: false,
preprocessor: (content, loaderContext) => {
content = content.replace(/__IMPORT_TEMPLATE_PATH__/g, rootPath(`/tmpls/${tmplName}`));
const combineHtmlPreprocessor = processNestedHtmlFactory(rootPath, rootPath(`/tmpls/${tmplName}`));
const combined = combineHtmlPreprocessor(content, loaderContext);
return fieldConverter(combined, {
context: loaderContext,
fieldMapPath: rootPath(fieldMapPath),
formKey: FORM_KEY,
});
},
},
},
],
},
],
},
plugins: [
new webpack.NormalModuleReplacementPlugin(/__IMPORT_TEMPLATE_PATH__/, (res) => {
res.request = res.request.replace(/__IMPORT_TEMPLATE_PATH__/g, `${__dirname}/tmpls/${tmplName}`);
}),
new webpack.NormalModuleReplacementPlugin(/__IMPORT_FIELDMAP_PATH__/, (res) => {
res.request = res.request.replace(/__IMPORT_FIELDMAP_PATH__/g, fieldMapPath);
}),
new webpack.NormalModuleReplacementPlugin(/__IMPORT_TEMPLATE_INIT_SCRIPT__/, (res) => {
res.request = res.request.replace(
/__IMPORT_TEMPLATE_INIT_SCRIPT__/g,
`${__dirname}/${tmplSettings.initScript}`
);
}),
new webpack.NormalModuleReplacementPlugin(/__FORM_KEY__/, (res) => {
res.request = res.request.replace(/__FORM_KEY__/g, FORM_KEY);
}),
new HtmlWebpackPlugin({
inject: true,
chunks: [tmplName],
template: `src/client/dev/index.ejs`,
filename: `${tmplName}.html`,
}),
],
};
config.entry[tmplName] = `${__dirname}/src/client/dev/main.js`;
return config;
};
const getMainConfig = (env, tmplSettings) => {
var config = {};
config.devtool = 'eval-cheap-module-source-map';
config.mode = 'development';
config.optimization = {
usedExports: true,
};
config.resolve = {
fallback: { assert: false },
extensions: ['.cjs', '.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.css', '.scss', '.svelte'],
modules: ['src', 'lib', 'node_modules', 'tmpls'],
alias: {
vendor: __dirname + '/lib/vendor',
jquery: __dirname + '/lib/vendor-adapters/jquery-global-adapter',
jqueryNonGlobal: __dirname + '/node_modules/jquery',
moment: __dirname + '/lib/vendor-adapters/moment-global-adapter',
momentNonGlobal: __dirname + '/node_modules/moment',
xdoc: __dirname + '/src/xdoc',
client: __dirname + '/src/client',
node_modules: 'node_modules',
test: __dirname + '/src/test',
svelte: __dirname + '/node_modules/svelte',
src: __dirname + '/src',
tmpls: __dirname + '/tmpls',
},
};
pipe(addTemplateAliases)(config.resolve.alias);
// console.log('aliases = ', config.resolve.alias);
config.resolveLoader = {
modules: ['node_modules', path.resolve(__dirname, 'build-utils', 'loaders')],
};
config.output = {
path: __dirname + '/dist/dev',
filename: '[name].js',
};
config.module = {
rules: [
{
test: /\.(svelte)$/,
use: {
loader: 'svelte-loader',
options: {
compilerOptions: {
dev: true,
},
preprocess: sveltePreprocess({}),
// ignore a11y errors
onwarn: (warning, handler) => {
if (warning.code.toLowerCase().startsWith('a11y-')) {
return;
}
handler(warning);
},
},
},
},
{
test: /\.ts$/,
exclude: /node_modules/,
use: [
{
loader: 'esbuild-loader',
options: {
loader: 'ts',
target: 'es2020',
//onlyCompileBundledFiles: true,
//transpileOnly: true,
},
},
],
},
{
test: /\.c?m?jsx?$/,
resolve: {
fullySpecified: false,
},
use: { loader: 'esbuild-loader' },
exclude: {
and: [/node_modules/],
},
},
{
test: require.resolve('jquery'),
use: [
{
loader: 'expose-loader',
options: {
exposes: ['jQuery', '$'],
},
},
],
},
{
test: /\.dot$/,
use: [
{
loader: 'raw-loader',
},
],
},
{
test: /\.scss$/,
include: path.resolve(__dirname, 'src/client/dev'),
use: [
'style-loader',
{
loader: 'css-loader',
options: { url: false, sourceMap: true },
},
{
loader: 'sass-loader',
options: {
additionalData: `$templateId: '${tmplSettings.templateId}';`,
},
},
{
loader: 'xdoc-sass-loader',
options: {
tmplPath: `${__dirname}/tmpls/${env.tmpl}`,
},
},
],
},
{
test: /\.scss$/,
exclude: path.resolve(__dirname, 'src/client/dev'),
use: [
'style-loader',
{
loader: 'css-loader',
options: { url: false, sourceMap: true },
},
{
loader: 'sass-loader',
options: {
additionalData: `$templateId: '${tmplSettings.templateId}';`,
},
},
],
},
{
test: /\.less$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { url: false, sourceMap: true },
},
{
loader: 'less-loader',
options: { sourceMap: true },
},
],
},
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { sourceMap: true },
},
],
},
{
test: /\.woff2?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: 'url-loader?limit=10000',
},
{
test: /\.(ttf|eot|svg)(\?[\s\S]+)?$/,
use: 'file-loader',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: ['file-loader?name=images/[name].[ext]'],
},
],
};
// optionally disables pdf printing if narrative styling is not used within the passed in template
if (!fs.existsSync(`./tmpls/${env.tmpl}/narrative.scss`)) {
config.module.rules.push({
test: /pdf-print.js/,
loader: 'null-loader',
});
if (env.tmpl && process.env.BABEL_ENV !== 'test') {
console.log(`${env.tmpl} does not use narrative.scss. dev tool PDF printing disabled.`);
}
}
config.plugins = [
new CopyWebpackPlugin({
patterns: [
{
from: __dirname + '/server',
to: __dirname + '/dist/dev/server',
},
{
from: __dirname + '/node_modules/material-design-icons-iconfont/dist/fonts',
to: __dirname + '/dist/dev/server/global-resources/fonts',
},
{
from: __dirname + '/node_modules/tinymce',
to: __dirname + '/dist/dev/servlet/gwt/assets/tinymce',
},
],
}),
new webpack.ProgressPlugin(),
new webpack.ProvidePlugin({
autosize: 'autosize',
_: 'lodash',
doT: 'dot',
}),
new webpack.DefinePlugin({
__FORM_KEY: JSON.stringify(FORM_KEY),
__XDOC_CONTAINER_ID: JSON.stringify(XDOC_CONTAINER_ID),
__TEMPLATE_ID: JSON.stringify(tmplSettings.templateId),
__TEMPLATE_HEADER_ID: JSON.stringify(tmplSettings.templateHeaderId),
__TEMPLATE_BODY_ID: JSON.stringify(tmplSettings.templateBodyId),
__TEMPLATE_RDE_NAME__: JSON.stringify(env.tmpl),
__APP_ENV: "'DEV'",
__API_BASE_URL: "'" + (argv.apiUrl ?? '/servlet') + "'",
}),
];
return config;
};
const buildTmplSettings = (env) => {
const settings = {
templateId: 'NA',
templateHeaderId: undefined,
templateBodyId: undefined,
initScript: `tmpls/${env.tmpl}/init.js`,
};
// yarn test
// yarn watch supernote
// yarn watch without a template name - error
if (!env.ideAnalyzer) {
const hash = crypto.createHash('sha1');
hash.update(fs.readFileSync(settings.initScript) + fs.readFileSync(`tmpls/${env.tmpl}/template.html`));
settings.templateId = hash.digest('hex');
settings.templateHeaderId = uuidv4().replace(/-/g, '');
settings.templateBodyId = uuidv4().replace(/-/g, '');
}
return settings;
};
const knownEnvVars = ['WEBPACK_BUNDLE', 'WEBPACK_BUILD', 'WEBPACK_WATCH', 't', 'tmpl', 'template', '--template'];
function findTemplateName(env) {
const envKeys = Object.keys(env);
const unknownArguments = envKeys.filter((v) => !knownEnvVars.includes(v));
if (unknownArguments.length === 1) {
// if only one unknown arg, then it's the template name
return unknownArguments[0];
}
return undefined;
}
module.exports = async (env) => {
if (process.env.BABEL_ENV !== 'test') {
env.tmpl = env.tmpl ?? env.template ?? env.t ?? findTemplateName(env);
}
if (!env.tmpl) {
throw Error(`No template name given. Args given: ${Object.keys(env)}. use yarn watch TEMPLATE`);
}
if (env.tmpl === 'development') {
env.ideAnalyzer = true;
}
const tmplSettings = buildTmplSettings(env);
const webpackConfig = await getTmplConfig(env, tmplSettings);
return merge(
getMainConfig(env, tmplSettings),
process.env.WATCH_STATS === 'on' ? smp.wrap(webpackConfig) : webpackConfig
);
};I guess the interesting part of this config is that we're returning an async function instead of a complete object. But that's because we need to do some async actions before we have our complete config. As far as I know this type of setup is supported by webpack.
Also, I see that we're depending on env, and it looks like the only way for us to get the "env" parameter is to have module.exports be assigned to a function as opposed to an object.
see: https://webpack.js.org/guides/environment-variables/
@elirov Your final config seems to be lacking conditionNames: ['svelte']. I was struggling with the same issue. But neither module.exports = env => {...} nor module.exports = env => [...] seem to be a problem. I verified this by playing with https://github.com/sveltejs/template-webpack template.
For me it was definitively the missing conditionNames: ['svelte']
🤞
@elirov Sorry for the false information above! (env) => ... IS the problem. The template had an older version of svelte-loader. 3.1.5 barks if config returns a function. Maybe you can get rid of env by using "build": "cross-env NODE_ENV=production webpack" and const mode = process.env.NODE_ENV || 'development' as demonstrated in the template.
Returning multiple configurations won't work either. I would need this for an Electron Build (main and renderer configs.)
At least, I would expect module.exports = [config] from working without warnings.
All working flawlessly in 3.1.7:
mode.export = config
mode.export = [config]
mode.export = env => config
mode.export = env => [config]
Thank! 👍