Dynamic import fails when I start production builds
marcof-git opened this issue · 6 comments
Hi, i have an issue when building for production with 'run build' and using dynamic import().
If I use the static import all works:
import {featureBlock} from "../../blocks/featureBlock/featureBlock";
When i try to use dynamic import and lunch 'start' livesync all works. But if i lunch 'build' for production the console print this error:
bootstrap:126 Uncaught (in promise) ChunkLoadError: Loading chunk 0 failed.
(error: http://dev.palazzospinola.beniculturali.it/home/undefinedcore/feature-block-d7b74d18.js)
the dynamic import is like this:
main.js
import { scripts } from '../../../../plugins/ett-core-blocks/assets/scripts/scripts.js';
scripts.js
//import {featureBlock} from "../../blocks/featureBlock/featureBlock"; --> commented for the test
document.addEventListener("DOMContentLoaded", () => {
const featuredBlockDetector = document.querySelector('.feature-block');
if (featuredBlockDetector) {
import(/* webpackChunkName: "feature-block" */'../../blocks/featureBlock/featureBlock').then((ok)=>{
console.log('feature block loaded');
});
}
});
the project is like this:
module.exports = {
// Project Identity
appName: 'ettCoreTheme',
....
files: [{
name: 'core',
entry: {
theme: ['./assets/styles/main.scss', './assets/scripts/main.js']
},
webpackConfig: (config, merge, appDir, isDev) => {
let customRules = {
plugins: [
new webpack.ProvidePlugin({
Popper: ['popper.js', 'default'],
}),
new WriteFilePlugin({
test: /\.svg$/
})
],
module: {
rules: [
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: fileLoader,
options: getFileLoaderOptions(
appDir,
isDev,
false
),
}
]
},
],
},
};
return merge(config, customRules);
},
}],
outputPath: 'dist',
hasReact: false,
hasSass: true,
hasLess: false,
hasFlow: false,
externals: {
jquery: 'jQuery',
},
alias: undefined,
errorOverlay: true,
optimizeSplitChunks: true,
watch: ['./(templates|lib)/**/*.php','./*.php'],
packageFiles: ['inc/**', 'vendor/**', 'dist/**', '*.php', '*.md', 'readme.txt', 'languages/**', 'layouts/**', 'LICENSE', '*.css', ],
packageDirPath: 'package',
useBabelConfig: true,
in the babel config i put:
module.exports = function(api) {
api.cache(true);
return {
presets: [
["@babel/preset-env", {
"useBuiltIns": "entry",
"corejs": 3
}]
]
};
}
In the php:
$enqueue = new \WPackio\Enqueue('ettCoreTheme', 'dist', '1.0.0', 'theme', __FILE__);
$GLOBAL_ASSETS = $enqueue;
$manifest = $enqueue->getManifest('core');
$config = [
'js' => true,
'css' => true,
'js_dep' => [],
'css_dep' => [],
'in_footer' => true,
'media' => 'all',
];
$assets = $enqueue->getAssets('core', 'theme', $config);
$jses = $assets['js'];
$csses = $assets['css'];
foreach ($jses as $js) {
if ($config['js']) {
wp_enqueue_script($js['handle'], $js['url'], ['jquery_slim', 'underscore'], '1.0.0', true);
}
}
Any help? Thanks
Hi,
When you create an instance of \WPackio\Enqueue
it automatically hooks to WordPress (both front-end and admin) to print the needed script for things like dynamic imports to work. You can see it here
https://github.com/swashata/wpackio-enqueue/blob/master/inc/Enqueue.php#L121
My guess is, the way you are instantiating is either after admin_print_scripts
or somehow this is not fired at all.
Hey thanks for the reply.
I instantiate the scripts with:
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\\assets');
and for the admin:
add_action('admin_enqueue_scripts', __NAMESPACE__ . '\\ett_enqueue_custom_admin_style');
In the usual wordpress way.
Is there any different way that i should use with your script? With a different action?
If I don't use dynamic import() all works: the dev server and the production build.
Maybe is because i put the scripts in "footer" mode or did I enter deps? See [jquery_slim and underscore]
edit:
just for learn more:
i use to put in var --
$enqueue = new \WPackio\Enqueue('ettCoreTheme', 'dist', '1.0.0', 'theme', __FILE__);
then i cycle the assets with
$assets = $enqueue->getAssets('core', 'theme', $config);
$jses = $assets['js'];
foreach ($jses as $js) {
if ($config['js']) {
wp_enqueue_script($js['handle'], $js['url'], ['jquery_slim', 'underscore'], '1.0.0', true);
}
}
Hey, I tried this too: but the result is the same.
in the assets function() init by the wp_enqueue_scripts action -->
$enqueue = new \WPackio\Enqueue('ettCoreTheme', 'dist', '1.0.0', 'theme', __FILE__);
$config = [
'js' => true,
'css' => true,
'js_dep' => ['jquery_slim', 'underscore'],
'css_dep' => [],
'in_footer' => true,
'media' => 'all',
];
$enqueue->enqueue('core', 'theme', $config);
edit: just and update, I tried to put scripts in the head -> not working.
bootstrap:126 Uncaught (in promise) ChunkLoadError: Loading chunk 0 failed.
(error: http://dev.palazzospinola.beniculturali.it/undefinedcore/featureBlock-7a767946.js)
Hi,
I used the guide here https://wpack.io/guides/using-wpackio-enqueue/#why-call-it-early and it doesn't seem to work.
For a quick fix instead of wp_enqueue_scripts I used the wp_loaded hook and there are no errors.
But I'm not sure it's the correct way, especially for dependency management.
Hi,
wp_enqueue_scripts
is called after wp_head
so when you instantiate WPackio\Enqueue
in wp_enqueue_scripts
it will fail. wp_loaded
on the other hand is called before wp_head
so it works just fine.
You can instantiate WPackio\Enqueue
in init
or wp_loaded
and call $enqueue->enqueue()
on wp_enqueue_scripts
, that should also work.
Hi,
thank you for your help, now is working fine.
function.php
function initWpPack()
{
Pack::init();
}
add_action('init', __NAMESPACE__ . '\\initWpPack');
a Class
class Pack
{
private static $assets;
static function init()
{
if (self::$assets) {
return;
}
self::$assets = new \WPackio\Enqueue('CoreTheme', 'dist', '1.0.0', 'theme', __FILE__);
}
static function getPack()
{
return self::$assets;
}
}
then within the wp_enqueue_scripts
$assetsQueue = Pack::getPack();
$assetsQueue->enqueue('core', 'theme', $config);