Laravel Mix - Multiple Entry Points, Multiple Outputs

Viewed 2159

I have multiple files in the resources/js folder, with a structure like this:

.
├── commons.js
├── foo
|   ├── foo1.js
|   └── goo2.js
├── bar
|   ├── ram1.js
|   └── ram2.js
├── gopher
|   ├── for1.js
|   └── for2.js

How do I compile all these using Laravel-Mix, and output with the same file structure? The file structure would essentially look the same, but minified. The reason why I want to do this is because some files, like foo1.js, has stuff like this:

$(document).ready(function(){
    // commands that are only for this page
});

that would get evoked on every page, so I'm importing different files for different pages so that only certain pages would run $(document).ready() functions.

2 Answers

If it's just a plain javascript mix.scripts() solves your problem if your javascript files contains new syntax then you should use mix.js()

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

mix.scripts('resources/js/common.js', 'public/js/common.js')
    .scripts('resources/js/foo/foo1.js', 'public/js/foo/foo1.js')
    .scripts('resources/js/foo/goo2.js', 'public/js/foo/goo2.js')
    .scripts('resources/js/bar/ram1.js', 'public/js/foo/ram1.js')
    .scripts('resources/js/bar/ram2.js', 'public/js/foo/ram2.js')
    .scripts('resources/js/gopher/for1.js', 'public/js/foo/for1.js')
    .scripts('resources/js/gopher/for2.js', 'public/js/foo/for2.js')

And to minify you should run npm run production

Edit
You can create a variable to store your folders path like so

const mix = require('laravel-mix')

const base = 'resources/js/'

const paths = {
    base: base,
    foo: base + 'foo/',
    bar: base + 'bar/',
    gopher: base + 'gopher/',
}

mix.scripts(paths.base + 'common.js', 'public/js/common.js')
    .scripts(paths.foo + 'foo1.js', 'public/js/foo/foo1.js')
    .scripts(paths.foo + 'goo2.js', 'public/js/foo/goo2.js')
    .scripts(paths.bar + 'ram1.js', 'public/js/foo/ram1.js')
    .scripts(paths.bar + 'ram2.js', 'public/js/foo/ram2.js')
    .scripts(paths.gopher + 'for1.js', 'public/js/foo/for1.js')
    .scripts(paths.gopher + 'for2.js', 'public/js/foo/for2.js')

I would use fs to recursively run through the files:

const fs = require('fs');
const path = require('path');
const isFile = (pathItem) => !!path.extname(pathItem);

const mapScripts = (fromDir,toDir) => {
  var dirs = fs.readdirSync(fromDir, 'utf8');
  dirs.forEach( subDir => {
    isFile(`${fromDir}/${subDir}`)
    ? mix.scripts(`${fromDir}/${subDir}`, `${toDir}/${subDir}`)
    : mapScripts(`${fromDir}/${subDir}`, `${toDir}/${subDir}`)
  })
}

Then call it on your directory:

mapScripts('resources/js', 'public/js');

You can do something similar with any mix API method, e.g. mix.css, mix.less, etc

Related