Skip to content

Commit

Permalink
Merge pull request #7 from eclipse-researchlabs/solve-vue-sass-issue
Browse files Browse the repository at this point in the history
added vue-sass package and fix node-sass version
  • Loading branch information
goncalorolo authored Jul 12, 2022
2 parents df460e9 + 1b422b3 commit 969539e
Show file tree
Hide file tree
Showing 5 changed files with 239 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/vue-sass/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.npm
62 changes: 62 additions & 0 deletions packages/vue-sass/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Integrate sass and scss with vue single-file components for Meteor

Compatibility: **Vue 1.x, Vue 2.x**

This meteor package adds [sass](http://sass-lang.com) support in your single-file `.vue` components.

## Installation

meteor add akryum:vue-sass


## Usage

```html
<style lang="scss">
$message-color: grey;
.message {
color: $message-color;
}
</style>

<style lang="sass">
$message-color: grey
.message
color: $message-color
</style>
```
You can import files with absolute or relative path:
```html
<style scoped lang="sass">
// Absolute path in the project
@import ~imports/ui/colors.sass
// Relative path
@import ../../imports/ui/colors.sass
</style>
```
## Config
In project `package.json`, you can add more folders for the sass file resolution:
```json
{
"vue": {
"css": {
"sass": {
"includePaths": [
"node_modules"
],
}
}
},
}
```
---
LICENCE ISC - Created by Guillaume CHAU (@Akryum)
25 changes: 25 additions & 0 deletions packages/vue-sass/package.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Package.describe({
name: 'akryum:vue-sass',
version: '0.1.2',
summary: 'Add sass and scss support for vue components',
git: 'https://github.com/Akryum/meteor-vue-component',
documentation: 'README.md',
})

Package.registerBuildPlugin({
name: 'vue-component-sass',
use: [
'[email protected]',
],
sources: [
'vue-sass.js',
],
npmDependencies: {
'node-sass': '4.14.0',
'meteor-project-path': '0.0.3',
},
})

Package.onUse(function (api) {
api.use('isobuild:[email protected]')
})
137 changes: 137 additions & 0 deletions packages/vue-sass/vue-sass.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import path from 'path'
import fs from 'fs'
import sass from 'node-sass'
import { Meteor } from 'meteor/meteor'

global.vue = global.vue || {}
global.vue.lang = global.vue.lang || {}

function resolveImport (dependencyManager) {
return function (url, prev, done) {
let resolvedFilename
url = url.replace(/^["']?(.*?)["']?$/, '$1')
if (url.indexOf('~') === 0 || url.indexOf('/') === 0) {
resolvedFilename = url.substr(1)
/* } else if (url.indexOf('{') === 0) {
resolvedFilename = decodeFilePath(url) */
} else {
let currentDirectory = path.dirname(prev === 'stdin' ? this.options.outFile : prev)
resolvedFilename = path.resolve(currentDirectory, url)
}
const importPaths = [resolvedFilename]
const pkg = require('package.json') // can not be moved outside. Reqired here to get the package.json of the project that is being run

try {
// get the package.json config option and create paths for the requested file.
pkg.vue.css.sass.includePaths.forEach((str) => {
importPaths.push(path.resolve(str, url))
})
} catch (e) {
// Ignore error. package.json option is not set.
}

const resolvedNames = importPaths.map(discoverImportPath).filter(
fileName => fileName !== null && typeof fileName !== 'undefined'
)

if (resolvedNames.length < 1) {
done(new Error('Unknown import (file not found): ' + url))
} else {
dependencyManager.addDependency(resolvedNames[0])

done({
file: resolvedNames[0],
})
}
}
}

function discoverImportPath (importPath) {
const potentialPaths = [importPath]
const potentialFileExtensions = ['scss', 'sass']

if (!path.extname(importPath)) {
potentialFileExtensions.forEach(extension => potentialPaths.push(`${importPath}.${extension}`))
}
if (path.basename(importPath)[0] !== '_') {
[].concat(potentialPaths).forEach(potentialPath => potentialPaths.push(`${path.dirname(potentialPath)}/_${path.basename(potentialPath)}`))
}

for (let i = 0, potentialPath = potentialPaths[i]; i < potentialPaths.length; i++, potentialPath = potentialPaths[i]) {
if (fs.existsSync(potentialPaths[i]) && fs.lstatSync(potentialPaths[i]).isFile()) {
return potentialPath
}
}

return null
}

// function decodeFilePath (filePath) {
// const match = filePath.match(/^{(.*)}\/(.*)$/)
// if (!match)
// {throw new Error('Failed to decode Sass path: ' + filePath)}

// if (match[1] === '') {
// // app
// return match[2]
// }

// return 'packages/' + match[1] + '/' + match[2]
// }

global.vue.lang.scss = Meteor.wrapAsync(function ({
source,
basePath,
inputFile,
dependencyManager,
}, cb) {
if (!source.trim()) {
cb(null, { css: '' })
return
}
sass.render({
data: source,
importer: resolveImport(dependencyManager),
outFile: inputFile.getPathInPackage() + '.css',
sourceMap: true,
sourceMapContents: true,
}, function (error, result) {
if (error) {
cb(error, null)
} else {
cb(null, {
css: result.css.toString(),
map: result.map.toString(),
})
}
})
})

global.vue.lang.sass = Meteor.wrapAsync(function ({
source,
basePath,
inputFile,
dependencyManager,
}, cb) {
if (!source.trim()) {
cb(null, { css: '' })
return
}
sass.render({
data: source,
importer: resolveImport(dependencyManager),
outFile: basePath + '.css',
sourceMap: true,
sourceMapContents: true,
indentedSyntax: true,
}, function (error, result) {
if (error) {
cb(error, null)
} else {
cb(null, {
css: result.css.toString(),
map: result.map.toString(),
})
}
})
})

0 comments on commit 969539e

Please sign in to comment.