From 21c95113dd4c34198ae7fdbfd019e5f8fb46460a Mon Sep 17 00:00:00 2001 From: YiSiWang <597222964@qq.com> Date: Wed, 12 Oct 2016 17:13:25 +0800 Subject: [PATCH 1/6] add test --- test/fixtures/css-modules.vue | 20 ++++++++++++++++++++ test/test.js | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 test/fixtures/css-modules.vue diff --git a/test/fixtures/css-modules.vue b/test/fixtures/css-modules.vue new file mode 100644 index 000000000..8646cb868 --- /dev/null +++ b/test/fixtures/css-modules.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/test/test.js b/test/test.js index c7327255f..3f546dff9 100644 --- a/test/test.js +++ b/test/test.js @@ -377,4 +377,37 @@ describe('vue-loader', function () { done() }) }) + + it('css-modules', function (done) { + test({ + entry: './test/fixtures/css-modules.vue' + }, function (window) { + var module = window.vueModule + + // get local class name + var className = module.computed.style().red + expect(className).to.match(/^_/) + + // class name in style + var style = [].slice.call(window.document.querySelectorAll('style')).map(function (style) { + return style.textContent + }).join('\n') + expect(style).to.contain('.' + className + ' {\n color: red;\n}') + + // animation name + var match = style.match(/@keyframes\s+(\S+)\s+{/) + expect(match).to.have.length(2) + var animationName = match[1] + expect(animationName).to.not.equal('fade') + expect(style).to.contain('animation: ' + animationName + ' 1s;') + + // default module + pre-processor + scoped + var anotherClassName = module.computed.$style().red + expect(anotherClassName).to.match(/^_/).and.not.equal(className) + var id = '_v-' + hash(require.resolve('./fixtures/css-modules.vue')) + expect(style).to.contain('.' + anotherClassName + '[' + id + ']') + + done() + }) + }) }) From e388186c571e5016e9386eb245e20910427a57a3 Mon Sep 17 00:00:00 2001 From: YiSiWang <597222964@qq.com> Date: Wed, 19 Oct 2016 17:58:07 +0800 Subject: [PATCH 2/6] add css module support with parser hack --- lib/loader.js | 63 +++++++++++++++++++++++++++++++++++++++++++++++---- test/test.js | 5 ++-- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/lib/loader.js b/lib/loader.js index f2a61c005..8d66c42ab 100644 --- a/lib/loader.js +++ b/lib/loader.js @@ -77,7 +77,7 @@ module.exports = function (content) { // disable all configuration loaders '!!' + // get loader string for pre-processors - getLoaderString(type, part, scoped) + + getLoaderString(type, part, index, scoped) + // select the corresponding part from the vue file getSelectorString(type, index || 0) + // the url to the actual vuefile @@ -94,17 +94,41 @@ module.exports = function (content) { function getRequireForImportString (type, impt, scoped) { return loaderUtils.stringifyRequest(loaderContext, '!!' + - getLoaderString(type, impt, scoped) + + getLoaderString(type, impt, -1, scoped) + impt.src ) } - function getLoaderString (type, part, scoped) { + function addCssModulesToLoader (loader, part, index) { + if (!part.module) return loader + return loader.replace(/((?:^|!)css(?:-loader)?)(\?[^!]*)?/, function (m, $1, $2) { + // $1: !css-loader + // $2: ?a=b + var option = loaderUtils.parseQuery($2) + option.modules = true + option.importLoaders = true + option.localIdentName = '[hash:base64]' + if (index !== -1) { + // Note: + // Class name is generated according to its filename. + // Different