-
-
Notifications
You must be signed in to change notification settings - Fork 621
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/generate loader #183
Merged
evenstensberg
merged 25 commits into
webpack:master
from
ianjsikes:feature/generate-loader
Sep 29, 2017
Merged
Changes from 20 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
63b3660
Add template files for loader yeoman generator
ianjsikes 14701f8
Create yeoman generator for a webpack loader project
ianjsikes 4349ba7
Add tests for loader-generator
ianjsikes b633b14
Add `mkdirp` dependency for loader-generator
ianjsikes 9de21fa
Add function to create yeoman env and run loader-generator
ianjsikes b6972a7
Add `generate-loader` command to webpack-cli
ianjsikes 91ab4ea
Copy loader templates from proper directory
ianjsikes 6a3e6a6
Add template files for plugin generator
ianjsikes 1aa6d30
Create yeoman generator for webpack plugins
ianjsikes 57fa953
Add function to create yeoman env and run plugin generator
ianjsikes d550206
Add cli command to generate plugin
ianjsikes 88eeede
Register generate- commands in yargs
ianjsikes b73a24d
Add template files for loader examples and tests
ianjsikes 0cb2f69
Copy loader test and example template files in generator
ianjsikes 7d6fd90
Add template files for plugin examples and tests
ianjsikes 4aa82f2
Copy plugin test and example template files in generator
ianjsikes bb164a8
Refactor generator file copying, switch .includes with .indexOf in CL…
ianjsikes 10ce3c2
Change `indexOf('foo') > -1` to `indexOf('foo') >= 0`
ianjsikes 4a8f738
Factor out generator copy utilities into separate module
ianjsikes 49c887e
Rewrite generators using a function that returns a customized generat…
ianjsikes e93c842
Merge branch 'master' into feature/generate-loader
ianjsikes a106d9d
Fix linting errors
ianjsikes 09aef62
Merge branch 'master' into feature/generate-loader
ianjsikes 41e2c9e
Remove //eslint-disable lines from template files
ianjsikes 5930f37
Merge branch 'feature/generate-loader' of https://github.com/ianjsike…
ianjsikes File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
const yeoman = require('yeoman-environment'); | ||
const LoaderGenerator = require('./loader-generator').LoaderGenerator; | ||
|
||
/** | ||
* Runs a yeoman generator to create a new webpack loader project | ||
*/ | ||
function loaderCreator() { | ||
let env = yeoman.createEnv(); | ||
const generatorName = 'webpack-loader-generator'; | ||
|
||
env.registerStub(LoaderGenerator, generatorName); | ||
|
||
env.run(generatorName); | ||
} | ||
|
||
module.exports = loaderCreator; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
const path = require('path'); | ||
const _ = require('lodash'); | ||
const webpackGenerator = require('../utils/webpack-generator'); | ||
|
||
/** | ||
* Formats a string into webpack loader format | ||
* (eg: 'style-loader', 'raw-loader') | ||
* | ||
* @param {string} name A loader name to be formatted | ||
* @returns {string} The formatted string | ||
*/ | ||
function makeLoaderName(name) { | ||
name = _.kebabCase(name); | ||
if (!/loader$/.test(name)) { | ||
name += '-loader'; | ||
} | ||
return name; | ||
} | ||
|
||
/** | ||
* A yeoman generator class for creating a webpack | ||
* loader project. It adds some starter loader code | ||
* and runs `webpack-defaults`. | ||
* | ||
* @class LoaderGenerator | ||
* @extends {Generator} | ||
*/ | ||
const LoaderGenerator = webpackGenerator( | ||
[{ | ||
type: 'input', | ||
name: 'name', | ||
message: 'Loader name', | ||
default: 'my-loader', | ||
filter: makeLoaderName, | ||
validate: str => str.length > 0, | ||
}], | ||
path.join(__dirname, 'templates'), | ||
[ | ||
'src/cjs.js.tpl', | ||
'test/test-utils.js.tpl', | ||
'test/unit.test.js.tpl', | ||
'test/functional.test.js.tpl', | ||
'test/fixtures/simple-file.js.tpl', | ||
'examples/simple/webpack.config.js.tpl', | ||
'examples/simple/src/index.js.tpl', | ||
'examples/simple/src/lazy-module.js.tpl', | ||
'examples/simple/src/static-esm-module.js.tpl', | ||
], | ||
[ | ||
'src/_index.js.tpl', | ||
], | ||
(gen) => ({ name: gen.props.name }) | ||
); | ||
|
||
module.exports = { | ||
makeLoaderName, | ||
LoaderGenerator, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
'use strict'; | ||
|
||
const makeLoaderName = require('./loader-generator').makeLoaderName; | ||
|
||
describe('makeLoaderName', () => { | ||
|
||
it('should kebab-case loader name and append \'-loader\'', () => { | ||
const loaderName = makeLoaderName('This is a test'); | ||
expect(loaderName).toEqual('this-is-a-test-loader'); | ||
}); | ||
|
||
it('should not modify a properly formatted loader name', () => { | ||
const loaderName = makeLoaderName('properly-named-loader'); | ||
expect(loaderName).toEqual('properly-named-loader'); | ||
}); | ||
|
||
}); |
11 changes: 11 additions & 0 deletions
11
lib/generate-loader/templates/examples/simple/src/index.js.tpl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import esmModule from './static-esm-module'; | ||
|
||
const getLazyModule = () => System.import('./lazy-module'); | ||
|
||
setTimeout(() => { | ||
getLazyModule.then((modDefault) => { | ||
console.log(modDefault); //eslint-disable-line | ||
}); | ||
}, 300); | ||
|
||
console.log(esmModule); //eslint-disable-line |
1 change: 1 addition & 0 deletions
1
lib/generate-loader/templates/examples/simple/src/lazy-module.js.tpl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default 'lazy'; |
1 change: 1 addition & 0 deletions
1
lib/generate-loader/templates/examples/simple/src/static-esm-module.js.tpl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default 'foo'; |
27 changes: 27 additions & 0 deletions
27
lib/generate-loader/templates/examples/simple/webpack.config.js.tpl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
const path = require('path'); | ||
|
||
module.exports = { | ||
entry: './src/index.js', | ||
output: { | ||
path: path.join(__dirname, 'example_dist'), | ||
filename: '[name].chunk.js', | ||
}, | ||
module: { | ||
rules: [ | ||
{ | ||
test: /\.js$/, | ||
use: [ | ||
{ | ||
loader: 'example-loader', | ||
options: {}, | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
resolveLoader: { | ||
alias: { | ||
'example-loader': require.resolve('../../src/'), | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/** | ||
* See the webpack docs for more information about loaders: | ||
* https://github.com/webpack/docs/wiki/how-to-write-a-loader | ||
*/ | ||
|
||
export default function loader(source) { | ||
const { loaders, resource, request, version, webpack } = this; | ||
|
||
const newSource = ` | ||
/** | ||
* <%= name %> | ||
* | ||
* Resource Location: ${resource} | ||
* Loaders chained to module: ${JSON.stringify(loaders)} | ||
* Loader API Version: ${version} | ||
* Is this in "webpack mode": ${webpack} | ||
* This is the users request for the module: ${request} | ||
*/ | ||
/** | ||
* Original Source From Loader | ||
*/ | ||
${source}`; | ||
|
||
return newSource; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('./index').default; |
3 changes: 3 additions & 0 deletions
3
lib/generate-loader/templates/test/fixtures/simple-file.js.tpl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import foo from "./foo"; // eslint-disable-line | ||
|
||
console.log(foo); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { | ||
runWebpackExampleInMemory, | ||
} from '../test/test-utils'; | ||
|
||
test('should run with no errors or warnings', async () => { | ||
const buildStats = await runWebpackExampleInMemory('simple'); | ||
const { errors, warnings } = buildStats; | ||
|
||
expect([...errors, ...warnings].length).toBe(0); | ||
}); | ||
|
||
test('should append transformations to JavaScript module', async () => { | ||
const buildStats = await runWebpackExampleInMemory('simple'); | ||
const { modules } = buildStats; | ||
|
||
const moduleToTest = modules[0].source()._source._value; //eslint-disable-line | ||
const loadedString = '* Original Source From Loader'; | ||
|
||
expect(moduleToTest).toEqual(expect.stringContaining(loadedString)); | ||
expect(moduleToTest).toMatchSnapshot(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import path from 'path'; | ||
import webpack from 'webpack'; | ||
import Promise from 'bluebird'; | ||
import MemoryFs from 'memory-fs'; | ||
|
||
const fs = new MemoryFs(); | ||
const unitTestFixtures = path.resolve(__dirname, 'fixtures'); | ||
|
||
/** | ||
* | ||
* | ||
* @param {string} fixtureName | ||
* @param {string} [withQueryString=''] | ||
* @returns {string} Absolute path of a file with query that is to be run by a loader. | ||
*/ | ||
function getFixtureResource(fixtureName, withQueryString = '') { | ||
return `${getFixture(fixtureName)}?${withQueryString}`; | ||
} | ||
|
||
/** | ||
* | ||
* | ||
* @param {string} fixtureName | ||
* @returns {string} Absolute path of a file with query that is to be run by a loader. | ||
*/ | ||
function getFixture(fixtureName) { | ||
return path.resolve(unitTestFixtures, `${fixtureName}.js`); | ||
} | ||
|
||
/** | ||
* | ||
* | ||
* @param {Object} withOptions - Loader Options | ||
* @returns {{loader: string, options: Object}} | ||
*/ | ||
function getLoader(withOptions) { | ||
return [{ loader: path.resolve(__dirname, '../dist/index.js'), options: withOptions }]; | ||
} | ||
|
||
/** | ||
* | ||
* | ||
* @param {string} exampleName | ||
* @returns {Object|Array} - Returns an object or array of objects representing the webpack configuration options | ||
*/ | ||
function getExampleConfig(exampleName) { | ||
return require(`../examples/${exampleName}/webpack.config.js`); //eslint-disable-line | ||
} | ||
|
||
/** | ||
* | ||
* | ||
* @param {string} exampleName - name of example inside of examples folder | ||
* @returns | ||
*/ | ||
async function runWebpackExampleInMemory(exampleName) { | ||
const webpackConfig = getExampleConfig(exampleName); | ||
const compiler = webpack(webpackConfig); | ||
|
||
compiler.outputFileSystem = fs; | ||
|
||
const run = Promise.promisify(compiler.run, { context: compiler }); | ||
const stats = await run(); | ||
|
||
|
||
const { compilation } = stats; | ||
const { errors, warnings, assets, entrypoints, chunks, modules } = compilation; | ||
const statsJson = stats.toJson(); | ||
|
||
return { | ||
assets, | ||
entrypoints, | ||
errors, | ||
warnings, | ||
stats, | ||
chunks, | ||
modules, | ||
statsJson, | ||
}; | ||
} | ||
|
||
export { getExampleConfig, runWebpackExampleInMemory, fs, getFixtureResource, getLoader, getFixture }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import fs from 'fs'; | ||
import Promise from 'bluebird'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be at 2nd line |
||
import { runLoaders } from 'loader-runner'; | ||
import { getFixtureResource, getFixture, getLoader } from './test-utils'; | ||
|
||
const runLoadersPromise = Promise.promisify(runLoaders); | ||
const readFilePromise = Promise.promisify(fs.readFile, { context: fs }); | ||
|
||
|
||
const loaders = getLoader(); | ||
|
||
describe('Example Loader Tests: Fixture: simple-file', () => { | ||
const fixtureName = 'simple-file'; | ||
const resource = getFixture(fixtureName); | ||
|
||
test('loaded file should be different', async () => { | ||
const originalSource = await readFilePromise(resource); | ||
const { result } = await runLoadersPromise({ resource: getFixtureResource(fixtureName), loaders }); | ||
|
||
expect(result).not.toEqual(originalSource); | ||
}); | ||
|
||
test('loader prepends correct information', async () => { | ||
const { result } = await runLoadersPromise({ resource: getFixtureResource(fixtureName), loaders }); | ||
const resultMatcher = expect.arrayContaining([ | ||
expect.stringContaining(' * Original Source From Loader'), | ||
]); | ||
|
||
expect(result).toEqual(resultMatcher); | ||
expect(result).toMatchSnapshot(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
const yeoman = require('yeoman-environment'); | ||
const PluginGenerator = require('./plugin-generator').PluginGenerator; | ||
|
||
/** | ||
* Runs a yeoman generator to create a new webpack plugin project | ||
*/ | ||
function pluginCreator() { | ||
let env = yeoman.createEnv(); | ||
const generatorName = 'webpack-plugin-generator'; | ||
|
||
env.registerStub(PluginGenerator, generatorName); | ||
|
||
env.run(generatorName); | ||
} | ||
|
||
module.exports = pluginCreator; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without the double asterisks (
/**
), it isn't recognized as a JSDoc comment. I could still remove it but you won't get any code hints from your editor.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, don't remove it. We should follow JSDoc everywhere. ESLint should be setup to enforce that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird, we've used it like the one I've proposed, may need to change everything then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we should change it everywhere then.