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 Auto Imports comes in. Gulp Auto Imports 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 Auto Imports 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 Auto Imports 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 Auto Imports, simply rearrange the import statements and you're done!
Note: if using Gulp Auto Imports with Sass files, it is best used in combination with Gulp Sass Glob, not as a complete replacement for it.
- Before and after Gulp Auto Imports
- Install
- Using the SCSS preset
- Using the automated Gulp task generator function
- 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
// main.scss (manually edited)
@import '../components/component-A/A.scss';
@import '../components/component-B/B.scss';
@import '../components/component-C/C.scss';
@import '../components/component-D/D.scss';
// main.scss (manually edited)
@import './auto-imports.scss';
// auto-imports.scss (auto-generated)
// retains the order that imports are declared in if edited manually
@import '../components/component-A/A.scss';
@import '../components/component-B/B.scss';
@import '../components/component-C/C.scss';
@import '../components/component-D/D.scss';
// main.js (manually edited)
import $ from 'jquery'
import A from '../components/component-A/A.js'
import B from '../components/component-B/B.js'
import C from '../components/component-C/C.js'
import D from '../components/component-D/D.js'
$(() => {
A()
B()
C()
D()
})
// main.js (manually edited)
import $ from 'jquery'
import autoImports from './auto-imports.js'
$(() => {
autoImports()
})
// auto-imports.js (auto-generated)
import A from "../components/component-A/A.js";
import B from "../components/component-B/B.js";
import C from "../components/component-C/C.js";
import D from "../components/component-D/D.js";
export default function() {
A();
B();
C();
D();
})
Install Gulp Auto Imports using the following command:
npm install gulp-auto-imports --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
| | | auto-imports.js
| | | main.js
| | scss
| | | config
| | | | [scss-config-files]
| | | auto-imports.scss
| | | main.scss
| build
| | assets
| | | css
| | | | main.css
| | | js
| | | | main.js
| gulpfile.js
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 = require('gulp')
var autoImports = require('gulp-auto-imports')
var sass = require('gulp-sass')
// Preset SCSS gulp-auto-imports task
gulp.task('sass:load', function () {
// Always relative to gulpfile.js even if this code is inside a folder
var dest = 'source/scss'
// Do not leave off the "return", it is vital!
return (
gulp
.src('./source/components/**/*.scss')
// Using the "scss" preset ("dest" must be provided here as well)
.pipe(autoImports({ preset: 'scss', dest: dest }))
.pipe(gulp.dest(dest))
)
})
/************\
Gulp 4
\************/
// Define a separate compile task
gulp.task('sass:compile', function () {
return gulp
.src('source/scss/main.scss')
.pipe(sass())
.pipe(gulp.dest('build/assets/css'))
})
// make "sass:load" run before "sass:compile" when "sass" is run
gulp.task('sass', gulp.series('sass:load', 'sass:compile'))
// Watch for changes
gulp.task('watch', function (done) {
gulp.watch('source/**/*.scss', gulp.series('sass'))
done()
})
/************\
Gulp 3
\************/
// Make "sass" dependent on "sass:load"
gulp.task('sass', ['sass:load'], function () {
return gulp
.src('source/scss/main.scss')
.pipe(sass())
.pipe(gulp.dest('build/assets/css'))
})
// Watch for changes
gulp.task('watch', function () {
gulp.watch('source/**/*.scss', ['sass'])
})
The scss
preset will apply the following default settings:
// scss preset default settings
{
format: `@import '$path';`,
fileName: 'auto-imports.scss',
retainOrder: true,
header: `
// This file is generated by gulp-auto-imports.
// 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-auto-imports.
// 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.
@import '../components/A/A.scss';
@import '../components/B/B.scss';
@import '../components/C/C.scss';
@import '../components/D/D.scss';
Due to the retainOrder: true
setting, you can rearrange the output. Gulp Auto Imports will preserve the order when it recompiles.
// Rearrange the output and Gulp Auto Imports will preserve it
// (Requires the `retainOrder` setting to be enabled)
@import '../components/D/D.scss';
@import '../components/A/A.scss';
@import '../components/C/C.scss';
@import '../components/B/B.scss';
If you add a new file to the system (eg. a ../components/A/A-two.scss
file) gulp-auto-imports will aim to group it with the other files found in the same folder.
// gulp-auto-imports will aim to group new files with files found in the same folder
@import '../components/D/D.scss';
@import '../components/A/A.scss';
@import '../components/A/A-two.scss'; // New file added
@import '../components/C/C.scss';
@import '../components/B/B.scss';
Add this line to your main scss file to auto-loaded your component styles:
// Import the auto-imports.scss file from main.scss
@import './auto-imports.scss';
You can now auto-load all of you're component scss files while still retaining full control over CSS source order! 😃
Making a single auto-imports file is ok using the standard method, however when you start making more than one auto-import file, the process can become quite cumbersome. This is why Gulp Auto Imports also comes with a task generator to make generating multiple auto-import files super easy.
For this example, we are going to generate three separate auto-import files. One for vars
, one for mixins
, and one for components
.
Here is the full code:
var gulp = require('gulp')
var { createAutoImportTask } = require('gulp-auto-imports')
// Create a function for generating auto-import gulp tasks
const createScssImporterTask = sourceFolder =>
createAutoImportTask({
sourceFolder,
// [optional] default = *all files*; Restrict imports to only target files with a specific extension name
fileExtension: 'scss',
// [optional] use this to resolve task name conflicts
taskPrefix: 'compile',
// [optional] default = true; will ignore the generated import file
ignoreImporterFile: true,
// Same settings object that you apply to the main gulp task
importerSettings: {
preset: 'scss',
// Note: `dest` will default to the source folder unless you define it here
// The generated output file will be ignored
},
})
// Destructure into separate importer and watcher tasks
const [scssVarsImporter, scssVarsImportWatcher] = createScssImporterTask(
'./source/scss/config/vars'
)
const [scssMixinsImporter, scssMixinsImportWatcher] = createScssImporterTask(
'./source/scss/config/mixins'
)
const [scssComponentsImporter, scssComponentsImportWatcher] =
createScssImporterTask('./source/scss/config/components')
// Gulp 4
gulp.task(
'scss-auto-imports',
gulp.parallel(
scssVarsImporter,
scssVarsImportWatcher,
scssMixinsImporter,
scssMixinsImportWatcher,
scssComponentsImporter,
scssComponentsImportWatcher
)
)
// Gulp 3
gulp.task('scss-auto-imports', [
scssVarsImporter,
scssVarsImportWatcher,
scssMixinsImporter,
scssMixinsImportWatcher,
scssComponentsImporter,
scssComponentsImportWatcher,
])
If you don't want to write out all the task variables, you can also use destructuring as a shortcut.
/**
* Use array destructuring as a shortcut
*/
// Gulp 4
gulp.task(
'scss-auto-imports',
gulp.parallel(
...createScssImporterTask('./source/scss/config/vars'),
...createScssImporterTask('./source/scss/config/mixins'),
...createScssImporterTask('./source/scss/config/mixins')
)
)
// Gulp 3
gulp.task('scss-auto-imports', [
...createScssImporterTask('./source/scss/config/vars'),
...createScssImporterTask('./source/scss/config/mixins'),
...createScssImporterTask('./source/scss/config/mixins'),
])
If you don't want to have gulp watch the files, simply don't pass the watcher into your gulp process.
/**
* Avoid watching files by not passing the generated watcher task into your main gulp process
*/
// Destructure to extract only the build task
const [scssVarsImporter] = createScssImporterTask('./source/scss/config/vars')
const [scssMixinsImporter] = createScssImporterTask(
'./source/scss/config/mixins'
)
const [scssComponetsImporter] = createScssImporterTask(
'./source/scss/config/mixins'
)
// Gulp 4 (no watching of files)
gulp.task(
'scss-auto-imports',
gulp.parallel(scssVarsImporter, scssMixinsImporter, scssComponetsImporter)
)
// Gulp 3 (no watching of files)
gulp.task('scss-auto-imports', [
scssVarsImporter,
scssMixinsImporter,
scssComponetsImporter,
])
The values that createAutoImportTask
returns are two task names in the format demonstrated below:
const taskNames = createAutoImportTask({
sourceFolder: './path/to/sourceFolder',
fileExtension: 'fileExtension',
taskPrefix: 'taskPrefix',
importerSettings: {
preset: 'scss',
},
})
taskNames ===
[
'taskPrefix:fileExtension:auto-imports:sourceFolder',
'taskPrefix:fileExtension:auto-imports-watcher:sourceFolder',
]
More details about the createAutoImportTask
function are documented in the createAutoImportTask.types.ts file.
Use in combination with Gulp Sass Glob
If you are using Gulp Auto Imports 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 Auto Imports tasks for each of them.
npm install gulp-sass-glob --save-dev
// Using Gulp Auto Imports in combination with Gulp Sass Glob in Gulp 3
var gulp = require('gulp')
var autoImports = require('gulp-auto-imports')
var sass = require('gulp-sass')
var sassGlob = require('gulp-sass-glob')
// Gulp Auto Imports task
gulp.task('sass:load', function () {
var dest = 'source/scss'
return gulp
.src('./source/components/**/*.scss')
.pipe(autoImports({ preset: 'scss', dest: dest }))
.pipe(gulp.dest(dest))
})
// Sass compile task (depends on 'sass:load' task)
gulp.task('sass', ['sass:load'], function () {
return gulp
.src('source/scss/main.scss')
.pipe(sassGlob()) // Sass Glob
.pipe(sass())
.pipe(gulp.dest('build/assets/css'))
})
// Using Gulp Auto Imports in combination with Gulp Sass Glob in Gulp 4
var gulp = require('gulp')
var autoImports = require('gulp-auto-imports')
var sass = require('gulp-sass')
var sassGlob = require('gulp-sass-glob')
// Gulp Auto Imports task
gulp.task('sass:load', function () {
var dest = 'source/scss'
return gulp
.src('./source/components/**/*.scss')
.pipe(autoImports({ preset: 'scss', dest: dest }))
.pipe(gulp.dest(dest))
})
// Sass compile task
gulp.task('sass:compile', function () {
return gulp
.src('source/scss/main.scss')
.pipe(sassGlob()) // Sass Glob
.pipe(sass())
.pipe(gulp.dest('build/assets/css'))
})
// Combined sass compile task
gulp.task('sass', gulp.series('sass:load', 'sass:compile'))
/**********************\
main.scss file
\**********************/
// Use Gulp Sass Glob to load config and helper files
@import 'vars/**/*.scss';
@import 'mixins/**/*.scss';
// Use the output from Gulp Auto Imports to load component files
@import 'auto-imports.scss';
/***************************\
auto-imports.scss file
(automatically generated)
\***************************/
@import '../components/one/one.scss';
@import '../components/two/two.scss';
@import '../components/three/three.scss';
@import '../components/four/four.scss';
- es6
- Import a set of functions using ES6
import
syntax and then call them on page load (import fileName from '../relative/path/fileName.js'
; then after DOM load:fileName()
). - es6_default_exports
- Import a bunch of ES6 JavaScript default exports and then export them all from one file (
export { default as fileName } from '../relative/path/fileName.js'
). - es6_named_exports
- Import a bunch of ES6 JavaScript named exports and then export them all from one file (
export { fileName } from '../relative/path/fileName.js'
). - es5
- Import a set of functions using
require()
and then call them on page load (var fileName = require('../relative/path/fileName.js')
; then after DOM load:fileName()
). - es5_default_exports
- Import a bunch of CommonJS default exports and then export them all from one file (
exports.fileName = require('../relative/path/fileName.js')
). - es5_named_exports
- Import a bunch of CommonJS named exports and then export them all from one file (
exports.fileName = require('../relative/path/fileName.js').fileName
). - ts
- Import a set of functions using TypeScript
import
syntax and then call them on page load (import fileName from '../relative/path/fileName'
; then after DOM load:fileName()
). - ts_default_exports
- Import a bunch of TypeScript default exports and then export them all from one file (
export { default as fileName } from '../relative/path/fileName'
). - ts_named_exports
- Import a bunch of TypeScript named exports and then export them all from one file (
export { fileName } from '../relative/path/fileName'
). - pug
- Intended for use with builds that use Pug as the templating language (
include ../relative/path/fileName.pug
). - jade
- For use on projects that haven't upgraded their old Jade powered projects to Pug yet (
include ../relative/path/fileName.jade
). - scss
- Sass import statements that use the newer SCSS style syntax (
@import '../relative/path/fileName.scss';
). - sass
- Sass import statements that use the older indented style syntax (
@import ../relative/path/fileName.sass
). - stylus
- Intended for use with the Stylus CSS generation language (
@import '../relative/path/fileName.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.
The preset setting just tells Gulp Auto Imports 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"
.pipe(autoImports({ preset: 'es6', fileName: 'different-file-name.js', dest: 'path/to/dest' }))
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 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 generate the auto imports, compile the JS, and then start watching files for changes.
(Rollup by default does not bundle CommonJS require()
statements).
'use strict';
// Import the auto imports plugin
var autoImports = require('gulp-auto-imports');
var gulp = require('gulp');
var rollup = require('@rollup/stream');
var sourcemaps = require('gulp-sourcemaps');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
gulp.task('js:load', function(){
const dest = './source/js';
return gulp.src([
'./source/components/**/*.js',
// exclude files and folders starting with an underscore
'!./source/components/{**/\_*,**/\_*/**}',
])
// Run the auto imports
.pipe(autoImports({ preset: 'es6', dest }))
.pipe(gulp.dest(dest));
})
var cache;
gulp.task('js:compile', function() {
return rollup({
// point to the entry file.
input: './source/js/main.js',
// use cache for better performance
cache: cache,
// Note: these options are placed at the root level in older versions of Rollup
output: {
// Output bundle is intended for use in browsers
// (iife = "Immediately Invoked Function Expression")
format: 'iife',
// Show source code when debugging in browser
sourcemap: true
}
})
.on('bundle', function(bundle) {
// update cache data after every bundle is created
cache = bundle;
})
// point to the entry file.
.pipe(source('main.js', './source/js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(sourcemaps.write('.'));
.pipe(gulp.dest('./build/assets/js'));
});
gulp.task('js', gulp.series('js:load', 'js:compile'));
gulp.task('js:watch', function(done){
gulp.watch(['./source/**/*.js'], gulp.series('js'));
done();
})
gulp.task('start', gulp.series('js', 'js:watch'));
'use strict'
// Import the auto imports plugin
var autoImports = require('gulp-auto-imports')
var gulp = require('gulp')
var rollup = require('@rollup/stream')
var sourcemaps = require('gulp-sourcemaps')
var source = require('vinyl-source-stream')
var buffer = require('vinyl-buffer')
gulp.task('js:load', function () {
const dest = './source/js'
return (
gulp
.src([
'./source/components/**/*.js',
// exclude files and folders starting with an underscore
'!./source/components/{**/_*,**/_*/**}',
])
// Run the auto imports
.pipe(autoImports({ preset: 'es6', dest }))
.pipe(gulp.dest(dest))
)
})
var cache
gulp.task('js', ['js:load'], function () {
return (
rollup({
// point to the entry file.
input: './source/js/main.js',
// use cache for better performance
cache: cache,
// Note: these options are placed at the root level in older versions of Rollup
output: {
// Output bundle is intended for use in browsers
// (iife = "Immediately Invoked Function Expression")
format: 'iife',
// Show source code when debugging in browser
sourcemap: true,
},
})
.on('bundle', function (bundle) {
cache = bundle
})
// point to the entry file.
.pipe(source('main.js', './source/js'))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./build/assets/js'))
)
})
gulp.task('js:watch', function () {
gulp.watch(['./source/**/*.js'], ['js'])
})
gulp.task('start', ['js', 'js:watch'])
Below is a modified version of the of the Gulp browserify + watchify recipe that has Gulp Auto Imports 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 auto-imports.js
file when it detects a JS file has been added to or removed from the components folder. The auto-generated auto-imports.js
file is imported into the main entry js file meaning Watchify is watching it for changes. When the new auto-imports.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 the auto imports plugin
var autoImports = require('gulp-auto-imports')
var watchify = require('watchify')
var browserify = require('browserify')
var gulp = require('gulp')
var source = require('vinyl-source-stream')
var buffer = require('vinyl-buffer')
var log = require('gulplog')
var sourcemaps = require('gulp-sourcemaps')
var customOpts = {
// entry file defined here
entries: ['./source/js/main.js'],
debug: true,
}
var opts = Object.assign({}, watchify.args, customOpts)
// Watch for changes then bundle
var b = watchify(browserify(opts))
b.on('update', bundle) // on any dep update, runs the bundler
b.on('log', log.info) // output build logs to terminal
function bundle() {
// Then bundle the code
return b
.bundle()
.on('error', log.error.bind(log, 'Browserify Error'))
.pipe(source('main.js'))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./build/assets/js'))
}
// File loader Gulp task
gulp.task('js:load', function () {
const dest = './source/js'
return (
gulp
.src([
'./source/components/**/*.js',
// exclude files and folders starting with an underscore
'!./source/components/{**/_*,**/_*/**}',
])
// Run the auto imports
.pipe(autoImports({ preset: 'es5', dest }))
.pipe(gulp.dest(dest))
)
})
///////////////////////////
// Gulp 3 specific code //
/////////////////////////
gulp.task('js', ['js:load'], bundle) // so you can run `gulp js` to build the file
gulp.task('watch', function () {
// Gulp 3 can't distinguish between 'add','unlink', and 'change' events
// so it also has to run on file changes
gulp.watch('./source/components/**/*.js', ['js:load'])
})
///////////////////////////
// Gulp 4 specific code //
/////////////////////////
gulp.task('js', gulp.series('js:load', bundle)) // so you can run `gulp js` to build the file
gulp.task('watch', function (done) {
var watcher = gulp.watch('./source/components/**/*.js')
//Gulp 4 has the advantage of only running when a file is added/removed, not changed
watcher.on('add', gulp.series('js:load'))
watcher.on('unlink', gulp.series('js:load'))
done()
})
Now that Gulp is set up to build a auto-imports JS file for you, import your generated file from main.js and call it as a function.
// Import auto-imports.js inside main.js
import autoImports from './auto-imports.js' // ES6
var autoImports = require('./auto-imports.js') // ES5
document.addEventListener('DOMContentLoaded', function () {
// Run the auto-imports code on page load
autoImports()
})
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 //
/////////
export default function on_page_load() {
// Place code here that you wish to run
// when the `autoImports()` function is called
}
/////////
// ES5 //
/////////
module.exports = function on_page_load() {
// Place code here that you wish to run
// when the `autoImports()` function is called
}
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.
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-auto-imports task
var gulp = require('gulp')
var autoImports = require('gulp-auto-imports')
gulp.task('sass:load', function () {
// Always relative to gulpfile.js even if this code is inside a folder
var dest = 'source/scss'
// Do not leave off the "return", it is vital!
return gulp
.src([
// These paths are always relative to gulpfile.js
'./source/components/**/*.scss',
// Ignore files & folders that start with underscores
'!./source/{**/_*,**/_*/**}',
])
.pipe(
autoImports({
// "$path" is replaced with a relative file path
format: '@import "$path";',
// destination folder (must match gulp.dest)
dest: dest,
// name of the output file
fileName: 'auto-imports.scss',
// Don't change the order that imports are currently in
retainOrder: true,
// Add a message to the top of the file
header: '// output from gulp-auto-imports',
})
)
.pipe(gulp.dest(dest))
})
The output of this Gulp task will look something like this:
// output from gulp-auto-imports
@import '../components/A/A.scss';
@import '../components/B/B.scss';
@import '../components/C/C.scss';
@import '../components/D/D.scss';
JS is slightly more complicated.
// Typical JS gulp-auto-imports task
var gulp = require('gulp')
var autoImports = require('gulp-auto-imports')
// Use an ES6 template literal for defining the template
// Node has supported them natively ever since v4.0.0
var template = `
$format[imports]
export default function(){
$format[functions]
}
`
gulp.task('js:load', function () {
var dest = 'source/js'
return gulp
.src([
'./source/components/**/*.js',
// Ignore files & folders that start with underscores
'!./source/{**/_*,**/_*/**}',
])
.pipe(
autoImports({
// Format is now split into an object holding named format strings
format: {
// "$name" is replaced with the name of the file
// "$path" is replaced with a relative path to the file
imports: 'import $name from "$path";',
// The indent is added here, not in the template
functions: ' $name();',
},
dest: dest,
fileName: 'auto-imports.js',
template: template,
})
)
.pipe(gulp.dest(dest))
})
The output from this task will look something like this:
// Generated auto-imports.js file
import one from '../components/one/one.js'
import two from '../components/two/two.js'
import three from '../components/three/three.js'
import four from '../components/four/four.js'
export default function () {
one()
two()
three()
four()
}
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.
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-auto-imports-is-awesome!123.js
=== converts to the $name ===
gulp_auto_imports_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.
The $fileName
placeholder in the format
setting holds the file name (excluding the extension) exactly as it is written.
// Assuming the full path is "./path/to/file-name.ext"
$fileName = file-name
The $ext
placeholder in the format
setting holds the file extension.
// Assuming the full path is "./path/to/file-name.ext"
$ext = ext
Note that you can get the full file name (including extension) by using this pattern in your format
setting:
// Assuming the full path is "./path/to/file-name.ext"
$fileName.$ext = file-name.ext
The $path
placeholder in the format
setting is replaced with a relative path that goes from the auto-imports output file to the file that is being loaded in.
$path = ./path/to/file-name.ext
Note 1: only one out of $path
, $noExtPath
, and $dir
can be declared in a single format rule and it can only be declared once.
Note 2: The retainOrder: true
setting only works with unaltered $path
placeholders.
The $noExtPath
placeholder in the format
setting is exactly the same as $path
except it will not add the file extension to the end.
$noExtPath = ./path/to/file-name
Note 1: only one out of $path
, $noExtPath
, and $dir
can be declared in a single format rule and it can only be declared once.
Note 2: The retainOrder: true
setting is not compatible with the $noExtPath
placeholder.
The $dir
placeholder in the format
setting stands for "directory" and is essentially the same as $path
except it does not include the file name or the extension.
// Assuming the full path is "./path/to/file-name.ext"
$dir = ./path/to
Note 1: only one out of $path
, $noExtPath
, and $dir
can be declared in a single format rule and it can only be declared once.
Note 2: The retainOrder: true
setting is not compatible with the $dir
placeholder.
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
import one from '../components/one/one.js'
import two from '../components/two/two.js'
import three from '../components/three/three.js'
import four from '../components/four/four.js'
export default function () {
// Notice the indent here
one()
two()
three()
four()
}
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 ...
.pipe(autoImports({
format: {
imports: 'import $name from "$path";',
// The indent is added here, not in the template
functions: ' $name();'
},
dest: dest,
fileName: 'auto-imports.js',
template: template
}))
That will produce the desired output:
// The result of correct indenting
import one from '../components/one/one.js'
import two from '../components/two/two.js'
import three from '../components/three/three.js'
import four from '../components/four/four.js'
export default function () {
// Notice the indent here
one()
two()
three()
four()
}
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 Auto Imports 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 Auto Imports will not alter the order of the existing $path
placeholder 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 Auto Imports 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 Auto Imports 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 auto-imports 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.
Note: The retainOrder: true
setting only works if you use an unaltered $path
placeholder. $noExtPath
, and $dir
are not supported.
The settings documentation can now be found in the index.d.ts file.
The Change log can be viewed on the Gulp Auto Imports GitHub releases page.