split-file-webpack-plugin
v0.0.9
Published
Webpack plugin to split files based on comment instructions
Downloads
7
Readme
split-file-webpack-plugin
This Webpack plugin splits individual input files into multiple output files based on comments in the input files. It creates source maps in the new files according to the source maps in the originals.
Why does this exist?
I wanted to write a Webpack loader that would use annotations on an input file to split
up frontend and backend code into separate output files. This is impossible in Webpack's
architecture, because loaders are assumed to be a string => string
map, not
string => string[]
. This plugin was born to enable loaders to effectively be
string => string[]
, as long as they use appropriate comment commands in their output
Javascript.
How do I use it?
Easy! First:
npm install --save-dev split-file-webpack-plugin
Then add it to your Webpack config in the plugins
array. For example:
var SplitFilePlugin = require("split-file-webpack-plugin");
module.exports = {
entry: {
app: "app.js"
},
output: {
path: __dirname + "/public"
},
plugins: [new SplitFilePlugin()]
};
But be warned! This is very early alpha code. It's extremely unstable and liable to change at any time without warning.
How does it work?
START-NEW-FILE
The directives in the source files take the following form:
To write a section of an input file to a new file, named foo.js
, include this comment
to start your block:
/* @split-file-plugin:START-NEW-FILE:foo.js */
Include this comment to end your block:
/* @split-file-plugin:END-SECTION */
For example, if you had an input file that looked like this, called main.js
:
// I will be in main.js
console.log("Hello main.js world");
/* @split-file-plugin:START-NEW-FILE:server.js */
// I will be in server.js
console.log("Hello server.js world");
/* @split-file-plugin:END-SECTION */
This plugin would output two files. One called main.js
:
// I will be in main.js
console.log("Hello main.js world");
And one file called server.js
:
// I will be in server.js
console.log("Hello server.js world");
Because START-NEW-FILE
might want to produce something that isn't JS (like
YAML), and Webpack assumes that all files are valid JS (and routinely is
passing files through parsers), it's allowed to end a START-NEW-FILE
line
with an open block-quote /*
. For example:
// I will be in main.js
console.log("Hello main.js world"); /*
/* @split-file-plugin:START-NEW-FILE:config.yaml */ /*
# I am a YAML file!
hello:
world: 1
foo: "bar"
/* @split-file-plugin:END-SECTION */
This outputs two files, main.js
and config.yaml
. They main.js
looks like:
// I will be in main.js
console.log("Hello main.js world");
And config.yaml
looks like:
# I am a YAML file!
hello:
world: 1
foo: "bar"
START-SPLIT
That's pretty much it, except for explaining the START-SPLIT
command. Suppose
that you have a common pre-amble that you want to include in a bunch of files,
like the output of Webpack resolving a bunch of import statements. START-SPLIT
will create a new file, but include everything in the source file that isn't
directed to another file with a command. It's the original file plus the
contents of the START-SPLIT
section. For example, suppose main.js
is:
import somelib;
/* @split-file-plugin:START-SPLIT:a.js */
console.log(somelib.foo());
/* @split-file-plugin:END-SECTION */
/* @split-file-plugin:START-SPLIT:b.js */
console.log(somelib.bar());
/* @split-file-plugin:END-SECTION */
This will output three files: main.js
will contain just the common code,
a.js
will contain common code and its START-SPLIT
section, and
b.js
will contain common code and its START-SPLIT
section.
main.js
:
import somelib;
a.js
:
import somelib;
console.log(somelib.foo());
b.js
:
import somelib;
console.log(somelib.bar());
There's one additional useful feature of START-SPLIT
, which is that it allows you to
specify custom export mappings for a given split. The motivating use case here is suppose
you want to export an AWS Lambda as a split, you need to be able to set
module.exports.handler =
as some function at the end of your file. If you set that in
the middle of your file, Webpack may swallow the export. So we put all the natural exports
of your files in a variable exported
, and allow you to write any exports you want after a
--
in the START-SPLIT
command. For example:
import somelib;
/* @split-file-plugin:START-SPLIT:a.js -- module.exports.handler = exported.a; */
export const a = 2;
/* @split-file-plugin:END-SECTION */
main.js
:
import somelib;
a.js
:
import somelib;
exported.a = 2;
module.exports.handler = exported.a;
For a good example of the use of this feature of START-SPLIT
, see the
babel-plugin-serverside-annotation project.
NO-SPLIT
This cuts off a section from any splits, leaving it only available in the root js file.
For example, suppose main.js
is:
import somelib;
/* @split-file-plugin:START-SPLIT:a.js */
console.log(somelib.foo());
/* @split-file-plugin:END-SECTION */
/* @split-file-plugin:NO-SPLIT */
console.log(somelib.bar());
/* @split-file-plugin:END-SECTION */
This will output two files: main.js
will contain just the common code,
a.js
will contain common code and its START-SPLIT
section, excluding the NO-SPLIT
section.
main.js
:
import somelib;
console.log(somelib.bar());
a.js
:
import somelib;
console.log(somelib.foo());
Administrivia
This is distributed under a GPLv3 license.