diff --git a/docs/en/README.md b/docs/en/README.md index 2bb3116c8..21e30088a 100644 --- a/docs/en/README.md +++ b/docs/en/README.md @@ -10,6 +10,7 @@ There are many cool features provided by `vue-loader`: - ES2015 enabled by default; - Allows using other Webpack loaders for each part of a Vue component, for example SASS for ` + + + This could be e.g. documentation for the component. + ``` `vue-loader` will parse the file, extract each language block, pipe them through other loaders if necessary, and finally assemble them back into a CommonJS module whose `module.exports` is a Vue.js component options object. @@ -66,6 +70,66 @@ More details can be found in [Using Pre-Processors](../configurations/pre-proces - By default, contents will be extracted and dynamically inserted into the document's `` as an actual ` +``` + +#### webpack.config.js + +``` js +// Webpack 2.x (^2.1.0-beta.25) +module.exports = { + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue', + // vue-loader options go here + options: { + loaders: { + unit-test: 'buble-loader', + } + } + } + ] + } +} +``` + + ### Src Imports If you prefer splitting up your `*.vue` components into multiple files, you can use the `src` attribute to import an external file for a language block: @@ -83,6 +147,13 @@ Beware that `src` imports follow the same path resolution rules to CommonJS `req diff --git a/test/fixtures/custom-language.vue b/test/fixtures/custom-language.vue new file mode 100644 index 000000000..3684d135b --- /dev/null +++ b/test/fixtures/custom-language.vue @@ -0,0 +1,31 @@ + + describe('example', function () { + it('basic', function (done) { + done(); + }) + }) + + + + This is example documentation for a component. + + + + + + + diff --git a/test/fixtures/custom-options.vue b/test/fixtures/custom-options.vue new file mode 100644 index 000000000..c8249bbd6 --- /dev/null +++ b/test/fixtures/custom-options.vue @@ -0,0 +1,7 @@ + + describe('example', function () { + it('basic', function (done) { + done(); + }) + }) + diff --git a/test/fixtures/unit-test.js b/test/fixtures/unit-test.js new file mode 100644 index 000000000..422357802 --- /dev/null +++ b/test/fixtures/unit-test.js @@ -0,0 +1,5 @@ + describe('example', function () { + it('basic', function (done) { + done(); + }) + }) diff --git a/test/test.js b/test/test.js index 2e7a8edd9..69e716505 100644 --- a/test/test.js +++ b/test/test.js @@ -57,12 +57,12 @@ function bundle (options, cb) { }) } expect(stats.compilation.errors).to.be.empty - cb(mfs.readFileSync('/test.build.js').toString()) + cb(mfs.readFileSync('/test.build.js').toString(), stats.compilation.warnings) }) } function test (options, assert) { - bundle(options, function (code) { + bundle(options, function (code, warnings) { jsdom.env({ html: '', src: [code], @@ -226,11 +226,10 @@ describe('vue-loader', function () { }) it('source map', function (done) { - var config = Object.assign({}, globalConfig, { + bundle({ entry: './test/fixtures/basic.vue', devtool: '#source-map' - }) - bundle(config, function (code) { + }, function (code, warnings) { var map = mfs.readFileSync('/test.build.js.map').toString() var smc = new SourceMapConsumer(JSON.parse(map)) var line @@ -266,7 +265,7 @@ describe('vue-loader', function () { }) it('extract CSS', function (done) { - bundle(Object.assign({}, globalConfig, { + bundle({ entry: './test/fixtures/extract-css.vue', vue: { loaders: { @@ -277,7 +276,7 @@ describe('vue-loader', function () { plugins: [ new ExtractTextPlugin('test.output.css') ] - }), function () { + }, function (code, warnings) { var css = mfs.readFileSync('/test.output.css').toString() css = normalizeNewline(css) expect(css).to.contain('h1 {\n color: #f00;\n}\n\nh2 {\n color: green;\n}') @@ -488,7 +487,7 @@ describe('vue-loader', function () { output: Object.assign({}, globalConfig.output, { libraryTarget: 'commonjs2' }) - }, function (code) { + }, function (code, warnings) { // http://stackoverflow.com/questions/17581830/load-node-js-module-from-string-in-memory function requireFromString(src, filename) { var Module = module.constructor; @@ -570,4 +569,124 @@ describe('vue-loader', function () { }) }) }) + + it('extract custom blocks to a separate file', function (done) { + bundle({ + entry: './test/fixtures/custom-language.vue', + vue: { + loaders: { + 'documentation': ExtractTextPlugin.extract('raw-loader') + } + }, + plugins: [ + new ExtractTextPlugin('doc.md') + ] + }, function (code, warnings) { + var unitTest = mfs.readFileSync('/doc.md').toString() + unitTest = normalizeNewline(unitTest) + expect(unitTest).to.contain('This is example documentation for a component.') + done() + }) + }) + + it('add custom blocks to the webpack output', function (done) { + bundle({ + entry: './test/fixtures/custom-language.vue', + vue: { + loaders: { + 'unit-test': 'babel-loader' + } + } + }, function (code, warnings) { + expect(code).to.contain('describe(\'example\', function () {\n it(\'basic\', function (done) {\n done();\n });\n})') + done() + }) + }) + + it('custom blocks work with src imports', function (done) { + bundle({ + entry: './test/fixtures/custom-import.vue', + vue: { + loaders: { + 'unit-test': 'babel-loader' + } + } + }, function (code, warnings) { + expect(code).to.contain('describe(\'example\', function () {\n it(\'basic\', function (done) {\n done();\n });\n})') + done() + }) + }) + + it('custom blocks can be removed from the output', function (done) { + bundle({ + entry: './test/fixtures/custom-language.vue', + vue: { + loaders: { + 'unit-test': 'null-loader' + } + } + }, function (code, warnings) { + expect(code).not.to.contain('describe(\'example\', function () {\n it(\'basic\', function (done) {\n done();\n });\n})') + done() + }) + }) + + it('no warnings when loaders are specified for all custom blocks', function (done) { + bundle({ + entry: './test/fixtures/custom-language.vue', + vue: { + loaders: { + 'documentation': 'null-loader', + 'unit-test': 'null-loader' + } + } + }, function (code, warnings) { + expect(warnings.length).to.equal(0) + done() + }) + }) + + it('warning should be raised when a loader is not specified for a custom block', function (done) { + bundle({ + entry: './test/fixtures/custom-language.vue', + vue: { + loaders: { + 'documentation': 'null-loader' + } + } + }, function (code, warnings) { + expect(warnings.length).to.equal(1) + expect(warnings[0].message).to.equal('Loader for custom block type "unit-test" not found in webpack configuration') + done() + }) + }) + + it('passes attributes as options to the loader', function (done) { + bundle({ + entry: './test/fixtures/custom-options.vue', + vue: { + loaders: { + 'unit-test': 'babel-loader!skeleton-loader' + } + }, + plugins: [ + new webpack.LoaderOptionsPlugin({ + options: { + skeletonLoader: { + procedure: function(content, sourceMap, callback, options) { + expect(options.foo).to.equal('bar'); + expect(options.opt2).to.equal('value2'); + + // Return the content to output. + return content; + } + } + } + }) + ] + }, function (code, warnings) { + expect(code).to.contain('describe(\'example\', function () {\n it(\'basic\', function (done) {\n done();\n });\n})') + done() + }) + }) })