Skip to content
This repository has been archived by the owner on Aug 5, 2021. It is now read-only.

Commit

Permalink
Merge pull request #17 from ryan-codingintrigue/master
Browse files Browse the repository at this point in the history
Add support for patterns when specifying emitFiles
  • Loading branch information
Poluektov Dmitriy authored Dec 2, 2018
2 parents 05c8d44 + e1a42f1 commit e9007c5
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 5 deletions.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,38 @@ Optional. Type: `boolean`

The `emitFiles` option is used to run the plugin as you normally would but prevents any files being emitted. This is useful for when you are using rollup to emit both a client side and server side bundle.

### fileName

Optional. Type: `string`

When `emitFiles` is `true`, the `fileName` option can be used to rename the emitted files. It accepts the following string replacements:

- `[hash]` - The hash value of the file's contents
- `[name]` - The name of the imported file, without it's file extension
- `[extname]` - The extension of the imported file, including the leading `.`
- `[dirname]` - The parent directory name of the imported file, including trailing `/`

Defaults to: `"[hash][extname]"`

### sourceDir

Optional. Type: `string`

When using the `[dirname]` replacement in `fileName`, uses this directory as the source directory to create the file path from rather than the parent directory of the imported file. For example:

*src/path/to/file.js*
```js
import png from "./image.png";
```
*rollup.config.js*
```js
url({
fileName: "[dirname][hash][extname]",
sourceDir: path.join(__dirname, "src")
})
```
Emitted File: `path/to/image.png`

# License

LGPL-3.0
30 changes: 25 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export default function url(options = {}) {
include = defaultInclude,
exclude,
publicPath = "",
emitFiles = true
emitFiles = true,
fileName = "[hash][extname]"
} = options
const filter = createFilter(include, exclude)

Expand All @@ -39,9 +40,24 @@ export default function url(options = {}) {
.update(buffer)
.digest("hex")
.substr(0, 16)
const filename = hash + path.extname(id)
data = `${publicPath}${filename}`
copies[id] = filename
const ext = path.extname(id)
const name = path.basename(id, ext)
// Determine the directory name of the file based
// on either the relative path provided in options,
// or the parent directory
const relativeDir = options.sourceDir
? path.relative(options.sourceDir, path.dirname(id))
: path.dirname(id).split(path.sep).pop()

// Generate the output file name based on some string
// replacement parameters
const outputFileName = fileName
.replace(/\[hash\]/g, hash)
.replace(/\[extname\]/g, ext)
.replace(/\[dirname\]/g, `${relativeDir}${path.sep}`)
.replace(/\[name\]/g, name)
data = `${publicPath}${outputFileName}`
copies[id] = outputFileName
} else {
const mimetype = mime.getType(id)
const isSVG = mimetype === "image/svg+xml"
Expand All @@ -62,8 +78,12 @@ export default function url(options = {}) {

await promise(mkpath, base)

return Promise.all(Object.keys(copies).map(name => {
return Promise.all(Object.keys(copies).map(async name => {
const output = copies[name]
// Create a nested directory if the fileName pattern contains
// a directory structure
const outputDirectory = path.join(base, path.dirname(output))
await promise(mkpath, outputDirectory)
return copy(name, path.join(base, output))
}))
}
Expand Down
47 changes: 47 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import assert from "assert"
import fs from "fs"
import path from "path"
import rimraf from "rimraf"
import {rollup} from "rollup"
import url from "../"
Expand All @@ -11,6 +12,7 @@ process.chdir(__dirname)

const svghash = "98ea1a8cc8cd9baf.svg"
const pnghash = "6b71fbe07b498a82.png"
const pngname = "png.png"

const asserts = {
svgInline: `var svg = "data:image/svg+xml,%3Csvg%3E%3Cpath%20d%3D%22%22%2F%3E%3C%2Fsvg%3E";\nexport default svg;`,
Expand Down Expand Up @@ -91,6 +93,51 @@ describe("rollup-plugin-url", () => {
)
)

it("should create a nested directory for the output, if required", () =>
run("./fixtures/png.js", { limit: 10, fileName: "subdirectory/[hash][extname]" })
.then(
() => Promise.all([
assertExists(`output/subdirectory/${pnghash}`)
])
)
)

it("should create a file with the name and extension of the file", () =>
run("./fixtures/png.js", { limit: 10, fileName: "[name][extname]" })
.then(
() => Promise.all([
assertExists(`output/${pngname}`)
])
)
)

it("should create a file with the name, hash and extension of the file", () =>
run("./fixtures/png.js", { limit: 10, fileName: "[name]-[hash][extname]" })
.then(
() => Promise.all([
assertExists(`output/png-${pnghash}`)
])
)
)

it("should prefix the file with the parent directory of the source file", () =>
run("./fixtures/png.js", { limit: 10, fileName: "[dirname][hash][extname]" })
.then(
() => Promise.all([
assertExists(`output/fixtures/${pnghash}`)
])
)
)

it("should prefix the file with the parent directory of the source file, relative to the sourceDir option", () =>
run("./fixtures/png.js", { limit: 10, fileName: "[dirname][hash][extname]", sourceDir: path.join(__dirname, "../") })
.then(
() => Promise.all([
assertExists(`output/test/fixtures/${pnghash}`)
])
)
)

it("should create multiple modules and inline files", () => {
return run(["./fixtures/svg.js", "./fixtures/png.js"], {}, true)
.then(
Expand Down

0 comments on commit e9007c5

Please sign in to comment.