1

I have a similar question here.

But I was NOT able to ask the right question.

I'm practicing with starter-blog template.

How do I use page specific javascript using the asset rev plugin and webpack? I don't want to manually add the js file inside the assets folder.

I want to write it inside the src folder and let webpack compile it to the assets folder.

Please help. Thank you.

user
  • 63
  • 5

3 Answers3

3

So what you want to compile a second JS file that's output seperately from the main JS file? In this case, you'll have to adjust the webpack config. The webpack.config.js in the starter project doesn't specify an explicit entry point, which means the default of src/index.js is used. You can overwrite this by specyfing one or multiple entry points as per the documentation. Include something like this in your webpack.config.js:

config = {
    // ...
    entry: {
        main: 'src/index.js',
        myCustomComponent: `src/myCustomComponent.js`,
    }
    // ...
}

Then create the specified file src/myCustomComponent.js and put your page-specific JavaScript in there.

This should work without further adjustments since the default output config in the starter project already supports multiple entry points by using placeholders for the target filename:

filename: devMode ? "[name].js" : "[name].[fullhash].js",

With the additional entry points, the webpack build step should result in two output files:

  • /web/assets/dist/index.js
  • /web/assets/dist/myCustomComponent.js

Both of those files will be compiled using the same rules specified by the Webpack config. In production mode, the output filenames will include the content hash (e.g. index.abcd1234.js, myCustomComponent.efgh5678.js). Those filenames will be written to the manifest by the Webpack manifest plugin, so now you can simply use the rev function to get the current asset path for your custom asset:

{% js rev('myCustomComponent.js') at head with { defer: true } %}

As a sidenote, I would recommend not using a starter template if you're just starting out. Unless you understand everything it's doing and the benefits it brings, it will just introduce complexity into your project that you're unable to debug or work productively with. Besides, the starter blog is, in my opinion, way more complicated than it needs to be. The webpack build in particular is really overkill, I've built much more complicated projects with a much simpler Webpack config. My recommendation would be to start with the blank starter project and use the starter blog as inspiration to draw from if you get stuck.

MoritzLost
  • 11,215
  • 5
  • 22
  • Thank you sir. This worked. But it compiles a very long js file for a simple console.log on my separate js file. Should I go with approach or not? What is the best practice of using a page specific js file Sir? – user Jun 04 '22 at 11:50
  • 1
    @user Yes, Webpack does tend to create larger files. It has some overhead of its own, and the Webpack config in the starter project also includes Babel, which will transpile and/or add polyfills to your code as required. Though make sure you check the compiled output for production, not dev mode, as the latter is much more verbose. If you don't want all of that for your page-specific JavaScript, you can also use the CopyWebpackPlugin to copy the JS file over without modifications. – MoritzLost Jun 06 '22 at 10:17
  • 1
    There isn't a best practice, it depends on what you need to Webpack build for. Again, if you don't need Webpack or don't see the benefit of it, start with something simpler and only add additional libraries and tools as you encounter problems where they will actually make your work easier. – MoritzLost Jun 06 '22 at 10:17
1

I Suggest to use Webpack with Laravel mix to fast approach.
Here is my setup. if need full file let me know.

const mix = require('laravel-mix');
mix.version();

mix.setPublicPath('web/assets'); mix.js('src/js/app.js', 'js');

mix.browserSync({ proxy: process.env.PRIMARY_SITE_URL, files: [ 'templates//*', 'web/assets//*', ], browser: process.env.LOCAL_BROWSER, injectChanges: true });

And instead of rev use mix.

1

Here is full Template

const mix = require('laravel-mix');

require('laravel-mix-tailwind'); require('laravel-mix-copy-watched');

// require('laravel-mix-purgecss'); // const purgeExclude = require('./purge.mix.js');

// const purgeContent = [ // "templates//*.php", // "templates//.twig", // "templates//.html", // "templates//*.json", // "templates//.js", // "templates//.rss", // "src/js//*.js", // "web/assets/icons//*.svg", // ];

/* |-------------------------------------------------------------------------- | Mix Asset Management |-------------------------------------------------------------------------- | | Mix provides a clean, fluent API for defining some Webpack build steps | for your Laravel applications. By default, we are compiling the CSS | file for the application as well as bundling up all the JS files. | */

mix.version(); // mix.sourceMaps(); mix.disableSuccessNotifications();

mix.options({ autoprefixer: { remove: false } });

mix.autoload({ jquery: ['$', 'window.$', 'window.jQuery'] });

mix.setPublicPath('web/assets');

mix.js('src/js/app.js', 'js');

/mix.sass( 'src/scss/all.scss', 'css' ).purgeCss({ enabled: (process.env.PURGE_CSS == "true" ? true : false), content: purgeContent, safelist: { standard: purgeExclude.whitelist } });/

mix.sass('src/scss/all.scss', 'css');

// mix.copyWatched( 'src/images', 'web/assets/images' ); mix.tailwind();

mix.browserSync({ proxy: process.env.PRIMARY_SITE_URL, files: [ 'templates//*', 'web/assets//*', ], browser: process.env.LOCAL_BROWSER, injectChanges: true });