Gulp File Loader
Important: This package has been renamed gulp-auto-imports. Please use that package instead.
Auto generate import-only files for any file type. SCSS, JS, Pug, whatever you want.
Are you sick of having to manually manage files that are purely just a bunch of import statements?
Wouldn't it be awesome if Gulp could just look at your file system and manage this busy work for you?
That is where Gulp File Loader comes in. Gulp File Loader will automatically manage these import-only files for you giving you more time to worry about the important stuff.
Due to it's high level of customization, Gulp File Loader is able to generate any import file you can imagine. SCSS, JS, Pug, PHP, you name it, it can create an import file for it (assuming the language supports import functionality in some way).
Gulp File Loader also has the ability to remember the order that imports are declared in. If you have ever had any experience with glob-loading SCSS files, you will know the pain of trying to get alpha.scss
to override styles in beta.scss
. With Gulp File Loader, simply rearrange the import statements and you're done!
Note: if using Gulp File Loader with Sass files, it is best used in combination with Gulp Sass Glob, not as a complete replacement for it.
Contents
- Before and after Gulp File Loader
- Install
- Using the SCSS preset
- Use in combination with Gulp Sass Glob
- All available presets
- JS configuration examples
- How to do custom configurations
- Understanding the
format
andtemplate
settings - The
retainOrder
setting - Settings reference guide
- Change Log
Before and after Gulp File Loader
SCSS Before
// main.scss (manually edited) ;;;;
SCSS After
// main.scss (manually edited) ;
// file-loader.scss (auto-generated) // retains the order that imports are declared in if edited manually ;;;;
JS before
// main.js (manually edited) ; ;;;;
JS after
// main.js (manually edited) ; ;
// file-loader.js (auto-generated) ;;;; { ; ; ; ;})
Install
Install Gulp File Loader using the following command:
npm install gulp-file-loader --save-dev
For my examples, I am assuming that the project folder structure looks like this:
[root]
| source
| | components
| | | [component-folders]
| | | | [component-name].js
| | | | [component-name].scss
| | js
| | | file-loader.js
| | | main.js
| | scss
| | | config
| | | | [scss-config-files]
| | | file-loader.scss
| | | main.scss
| build
| | assets
| | | css
| | | | main.css
| | | js
| | | | main.js
| gulpfile.js
Using the SCSS preset
Writing out all of the required settings manually for this plugin can be a bit tiresome. As of version 2.0.0 I've included some common preset settings that you can use as defaults. All you need to do for a basic SCSS set up is the following. You will need the gulp-sass
plugin for this to fully work. npm i gulp-sass -D
).
var gulp = ;var fileLoader = ;var sass = ; // Preset SCSS gulp-file-loader taskgulp /************\ Gulp 4\************/ // Define a separate compile taskgulp // make "sass:load" run before "sass:compile" when "sass" is rungulp; // Watch for changesgulp /************\ Gulp 3\************/ // Make "sass" dependent on "sass:load"gulp // Watch for changesgulp
The scss
preset will apply the following default settings:
// scss preset default settings format: '@import "$path";' fileName: 'file-loader.scss' retainOrder: true header: `// This file is generated by gulp-file-loader.// Save this file into source control.// You may rearrange the order of the imports however you like.// You may NOT make any other alterations to this file.`;
The output of the example 'sass:load'
task will look something like this:
// This file is generated by gulp-file-loader. // Save this file into source control. // You may rearrange the order of the imports however you like. // You may NOT make any other alterations to this file. ;;;;
Due to the retainOrder: true
setting, you can rearrange the output. Gulp File Loader will preserve the order when it recompiles.
// Rearrange the output and Gulp File Loader will preserve it // (Requires the `retainOrder` setting to be enabled) ;;;;
If you add a new file to the system (eg. a ../components/A/A-two.scss
file) gulp-file-loader will aim to group it with the other files found in the same folder.
// gulp-file-loader will aim to group new files with files found in the same folder ;;; // New file added ;;
Add this line to your main scss file to auto-loaded your component styles:
// Import the file-loader.scss file from main.scss ;
You can now auto-load all of you're component scss files while still retaining full control over CSS source order! 😃
Gulp Sass Glob
Use in combination withIf you are using Gulp File Loader to load scss files, it works best as a method used for loading your component files since those tend to require a specific order to work correctly.
Most of the time, your config files (files that hold nothing but Sass variables) and helper files (mixins, utility classes etc.) don't need to retain their order. It is both easier and cleaner to use Gulp Sass Glob to auto-load these types of files than it is to set up individual Gulp File Loader tasks for each of them.
npm install gulp-sass-glob --save-dev
Gulp 3 combination
// Using Gulp File Loader in combination with Gulp Sass Glob in Gulp 3 var gulp = ;var fileLoader = ;var sass = ;var sassGlob = ; // Gulp File Loader taskgulp // Sass compile task (depends on 'sass:load' task)gulp
Gulp 4 combination
// Using Gulp File Loader in combination with Gulp Sass Glob in Gulp 4 var gulp = ;var fileLoader = ;var sass = ;var sassGlob = ; // Gulp File Loader taskgulp // Sass compile taskgulp // Combined sass compile taskgulp;
Using a combination inside main.scss
/**********************\ main.scss file\**********************/ // Use Gulp Sass Glob to load config and helper files ;; // Use the output from Gulp File Loader to load component files ;
/***************************\ file-loader.scss file (automatically generated)\***************************/ ;;;;
All available presets
- es6
- JavaScript imports that use the modern import syntax (
import thing from './file.js';
). - es5
- JavaScript imports that use the old CommonJS syntax (
var thing = require('./file.js');
). - pug
- Intended for use with builds that use Pug as the templating language (
include ./file.pug
). - jade
- For use on projects that haven't upgraded their old Jade powered projects to Pug yet (
include ./file.jade
). - scss
- Sass import statements that use the newer SCSS style syntax (
@import "./file.scss";
). - sass
- Sass import statements that use the older indented style syntax (
@import ./file.sass
). - stylus
- Intended for use with the Stylus CSS generation language (
@import "./file.styl"
).
You can browse the available presets and see what their settings look like in the presets
folder. The presets are named after the file names in that folder.
If you would like other presets to be added, you can log an issue to request for a new preset to be added, or you can make a pull request to add one yourself.
Overriding a preset
The preset setting just tells Gulp File Loader what to use as the default settings.
You can override any of the preset settings by providing your own alternative setting. For example, to change the output file name, you can do this:
// Overriding the default preset setting for "fileName"
JS configuration examples
Adding this functionality to your JS compiler can be tricky since JS compilers generally don't run off typical gulp functionality for performance reasons.
Rollup
Rollup has a pretty straight forward integration. It is very similar to the Sass set up. It gets around the performance issues by allowing you to cache the last bundle that was generated.
Running gulp start
will run the file loader, compile the JS, and then start watching files.
(Rollup by default does not bundle CommonJS require()
statements).
Rollup in Gulp 4
'use strict'; // Import file loader pluginvar fileLoader = ; var gulp = ;var rollup = ;var sourcemaps = ;var source = ;var buffer = ; gulp var cache;gulp; gulp; gulp gulp;
Rollup in Gulp 3
'use strict'; // Import file loader pluginvar fileLoader = ; var gulp = ;var rollup = ;var sourcemaps = ;var source = ;var buffer = ; gulp var cache;gulp; gulp gulp;
Browserify
Below is a modified version of the of the Gulp browserify + watchify recipe that has Gulp File Loader installed.
Browserify gets around performance issues by using a special "Watchify" JS library instead of gulp.watch()
. You specify an entry file. Watchify watches for any changes to files that are imported from that entry file. It will also watch for changes to files imported from those imported files (and so on and so on forever).
The code below will generate a new file-loader.js
file when it detects a JS file has been added to or removed from the components folder. The auto-generated file-loader.js
file is imported into the main entry js file meaning Watchify is watching it for changes. When the new file-loader.js
file is generated, Watchify detects that the file has changed. This triggers Watchify to initiate a Browserify rebundle.
Most of the code below works in both both Gulp 3 and Gulp 4.
'use strict'; // Import file loader pluginvar fileLoader = ; var watchify = ;var browserify = ;var gulp = ;var source = ;var buffer = ;var log = ;var sourcemaps = ; var customOpts = // entry file defined here entries: './source/js/main.js' debug: true;var opts = Object; // Watch for changes then bundlevar b = ; b; // on any dep update, runs the bundlerb; // output build logs to terminal { // Then bundle the code return b ;} // File loader Gulp taskgulp ///////////////////////////// Gulp 3 specific code ///////////////////////////gulp; // so you can run `gulp js` to build the filegulp ///////////////////////////// Gulp 4 specific code ///////////////////////////gulp; // so you can run `gulp js` to build the filegulp
Making use of the generated JS file
Now that Gulp is set up to build a file-loader JS file for you, import your generated file from main.js and call it as a function.
// Import file-loader.js inside main.js; // ES6var fileLoader = ; // ES5 document;
Note that a typical component js file will need to export a function by default for this configuration to work.
// component js file example ///////// // ES6 /////////// { // Place code here that you wish to run // when the `fileLoader()` function is called} ///////// // ES5 ///////////module { // Place code here that you wish to run // when the `fileLoader()` function is called}
How to do custom configurations
Now that you know how to use presets, lets replicate some of these presets manually to show you how to use the plugin if the files you wish to load are not available as a preset.
Manual SCSS set up
I'll use SCSS as an example first because it is both simple and popular.
Create a gulp task that looks like this:
// Typical SCSS gulp-file-loader task var gulp = ;var fileLoader = ; gulp
The output of this Gulp task will look something like this:
// output from gulp-file-loader ;;;;
Manual JS set up
JS is slightly more complicated.
// Typical JS gulp-file-loader task var gulp = ;var fileLoader = ; // Use an ES6 template literal for defining the template// Node has supported them natively ever since v4.0.0var template = `$format[imports] export default function(){$format[functions]}`; gulp
The output from this task will look something like this:
// Generated file-loader.js file ;;;; { ; ; ; ;}
format
and template
settings
Understanding the It is recommended that you use an ES6 Template Literal (the back tick style strings) for creating the template rather than regular strings. Template Literals will allow you to define the markup found inside the output file exactly as written in a single string. Regular strings don't accept new lines so it makes writing the template much more difficult.
Remember that Template Literal's count all white space literally, so any white space you add to the template will appear in the final output. To avoid an odd looking output file, save the template to a template
variable outside of the gulp task so that there is no indentation to the side of it.
The template works by replacing each $format[formatName]
statement with a full list of imports formated in the specified way provided in the format
object.
If the format
setting is provided as a string, the template
setting is ignored. If format
is provided as an object, the template
setting is required.
$name
placeholder
The The $name
placeholder in the format
setting is replaced with the file name of the file. Any non-alphabetic and non-numeric characters are converted to underscores to prevent possible syntax errors.
./folder/path/gulp-file-loader-is-awesome!123.js
=== converts to the $name ===
gulp_file_loader_is_awesome_123
If there are duplicate file names, a number is added to the end of the name based on how many duplicates it has found to ensure that each name is unique.
./folder/one/thing.js
./folder/two/thing.js
=== converts to the $name ===
thing
thing_1
The $name
placeholder is excellent for use cases where you need to assign an import path to a variable name.
You can use the $name
placeholder as much as you like. That includes having the $name
placeholder appear multiple times in a single format rule. The $name
will always refer to the same import path.
$path
placeholder
The The $path
placeholder in the format
setting is replaced with a relative path that goes from the file-loader output file to the file that is being loaded in.
$path = ./path/to/file.ext
$path
can only be declared once per format rule.
Using indents
If you want indenting, the indenting should be added through the format
setting not the template
setting. If you indent the template, only the first item in the list will be indented. The rest will press hard up against the edge of the page.
For example, if you use this as your template:
// How NOT to indent your template var template = `$format[imports] export default function(){ // Notice the indent here $format[functions]}`;
You will end up with a JS file that looks like this:
// The result of incorrect indentation ;;;; { // Notice the indent here ;;;;}
Instead, apply indentation through the format
setting:
//How to apply correct indentation var template = `$format[imports] export default function(){ // Notice the indent here$format[functions]}`; // ... other Gulp code ...
That will produce the desired output:
// The result of correct indenting ;;;; { // Notice the indent here ; ; ; ;}
retainOrder
setting
The I briefly touched on the retainOrder
setting earlier, however there is a bit more to know about it.
In CSS, the order that styles are written in matters significantly. It is important that you are able to alter the order that files are loaded in if you wish to have full control over your CSS specificity.
Other globing methods (eg. @import "../path/to/components/**/*.scss";
) do not give you the ability to alter the order that the files are loaded in. You are generally restricted to loading files in alphabetical order. Gulp File Loader gives you back the ability to control the order that your CSS loads in with it's retainOrder
setting (introduced in v2.0.0).
By default retainOrder
is set to false
. When retainOrder
is set to true
, Gulp File Loader will not alter the order of the existing import paths if you manually edit them yourself. Make sure that if you enable the retainOrder
setting you save the output file into source control. This will ensure that your co-workers don't end up with a CSS file that is in a different order to yours.
Gulp File Loader will still delete old files from the list that don't exist any more.
If it detects that a new file is added to the system, Gulp File Loader will aim to keep that new file grouped with other files found in the same folder. (Prior to v2.1.0 it just dumped it at the bottom of the file). This means that new scss config file imports will be placed at the top of the file-loader file with the other config files. This gives all your component files access to the new config settings without you having to make any alterations to the imports file.
It will not retain any comments or other alterations to the file. It will only retain the order that the imports were announced in.
Settings reference guide
- header
- A string of text that is added to the top of the output file when it is generated. This is good for leaving comments like "
// Do not edit this file
". - footer
- A string of text that is added to the bottom of the output file when it is generated. This might be useful for calling a custom function at the bottom of the file after all the imports have been loaded.
- format
- The format setting dictates the format of each import line in the generated file. It can either be a string or an object holding multiple named strings. If you provide an object to this setting, the
template
setting is also required. Use the$path
and$name
placeholders inside the string to determine where the file path and name should go. - template
- The template setting holds a string that dictates the overall structure of the generated file. Use
$format[formatName]
placeholders in the template string to dictate where each format should be used in the output file. If theformat
setting is provided as a string, thetemplate
setting is ignored. - fileName
- A string holding the file name for the output file. The file extension must be included.
- dest
- Should be identical to the setting used in
gulp.dest
. It determines where the output file is sent after processing. It is always a relative path fromgulpfile.js
, not a relative path from the current file. Example:"path/to/destination"
. Thegulp.dest
setting is unavailable at the time the plugin is called, thus the setting needs to be provided explicitly. - retainOrder
- This is set to
false
by default. When set totrue
, it will never alter the order that imports are loaded in. This gives you the ability to manually edit the output file to achieve the desired import order. Make sure to save the output file into source control so that your team mates end up with a file that is in the same order as yours. - preset
- Use a set of predefined default settings rather than configuring all of the settings yourself. You can view the available presets and the settings that they provide in the
presets
folder.
Change Log
The Change log can be viewed on the Gulp File Loader GitHub releases page.