-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
2,450 additions
and
1,222 deletions.
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
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,140 @@ | ||
/** | ||
* @package DPCalendar | ||
* @copyright Copyright (C) 2024 Digital Peak GmbH. <https://www.digital-peak.com> | ||
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL | ||
*/ | ||
|
||
// The needed libs | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const sass = require('sass'); | ||
const watch = require('node-watch'); | ||
const util = require('./util'); | ||
|
||
async function buildAsset(root, asset, config) { | ||
// Traverse the directory and build the assets | ||
util.getFiles(root + '/' + asset.src).forEach((file) => { | ||
// Files starting with an underscore are treated as imports and do not need to be built | ||
if (path.basename(file).indexOf('_') === 0 || file.indexOf('.js') !== -1) { | ||
return; | ||
} | ||
|
||
// Transpile the file | ||
transpile(file, file.replace(asset.src, asset.dest).replace('scss', 'css').replace('.css', '.min.css'), config); | ||
}); | ||
}; | ||
|
||
function watchAssets(root, assets) { | ||
console.log('Building index for ' + root); | ||
|
||
let index = []; | ||
let filesToWatch = []; | ||
|
||
// Load extra dev assets when available | ||
if (assets.localDev) { | ||
assets.localDev.forEach((asset) => filesToWatch.push(root + '/' + asset)); | ||
} | ||
|
||
assets.local.forEach((asset) => { | ||
if (!fs.existsSync(root + '/' + asset.src)) { | ||
return; | ||
} | ||
|
||
filesToWatch.push(root + '/' + asset.src); | ||
|
||
// If it is a single file add it to the index only | ||
if (!fs.lstatSync(root + '/' + asset.src).isDirectory()) { | ||
index[root + '/' + asset.src] = root + '/' + asset.dest; | ||
return; | ||
} | ||
|
||
// Traverse the directory and build the assets | ||
util.getFiles(root + '/' + asset.src).forEach(file => { | ||
// Files starting with an underscore are treated as imports and do not need to be built | ||
if (path.basename(file).indexOf('_') === 0 || file.indexOf('.js') !== -1) { | ||
return; | ||
} | ||
|
||
index[file] = file.replace(asset.src, asset.dest).replace('scss', 'css'); | ||
}); | ||
}); | ||
|
||
console.log('Watching ' + root + ' for changes'); | ||
watch( | ||
filesToWatch, | ||
{ recursive: true }, | ||
(type, file) => { | ||
if (type != 'update' || file.indexOf('.js') !== -1) { | ||
return; | ||
} | ||
|
||
if (index[file] == null) { | ||
console.log('Building the whole extension because of file: ' + file.replace(root + '/', '')); | ||
assets.local.forEach((asset) => buildAsset(root, asset, assets.config)); | ||
return; | ||
} | ||
|
||
console.log('Transpiling the file ' + file.replace(root + '/', '') + ' to ' + index[file].replace(root + '/', '')); | ||
try { | ||
transpile(file, index[file], assets.config); | ||
} catch (e) { | ||
console.log(e.message); | ||
} | ||
} | ||
); | ||
} | ||
|
||
/** | ||
* Transpile function which can handle Javascript, SASS and CSS files. | ||
* | ||
* @param string source The full path of the source file | ||
* @param string destination The full path of the destination file | ||
* @param object config Some configuration options | ||
*/ | ||
function transpile(source, destination, config) { | ||
// Ensure that the target directory exists | ||
if (!fs.existsSync(path.dirname(destination))) { | ||
fs.mkdirSync(path.dirname(destination), { recursive: true }); | ||
} | ||
|
||
// Transpile the files | ||
switch (path.extname(source).replace('.', '')) { | ||
case 'scss': | ||
case 'css': | ||
// Define the content and file path, based on the extension of the destination | ||
if (destination.indexOf('.min.css') > -1) { | ||
const result = sass.compile(source, { outFile: destination, style: 'compressed', loadPaths: [config.moduleRoot + '/node_modules'] }); | ||
|
||
// Write the minified content to the file | ||
fs.writeFileSync(destination, (config.docBlock ? config.docBlock + '\n' : '') + result.css.toString().trim()); | ||
return; | ||
} | ||
|
||
// Compile sass files | ||
const result = sass.compile(source, { | ||
outFile: destination, | ||
style: 'expanded', | ||
indentType: 'tab', | ||
indentWidth: 1, | ||
sourceMap: true, | ||
loadPaths: [config.moduleRoot + '/node_modules'] | ||
}); | ||
|
||
// Normalize the extension | ||
destination = destination.replace('.css', '.min.css'); | ||
|
||
// Write the map content to the destination file with the adjusted paths | ||
const mapRoot = destination.substring(0, destination.indexOf('/resources') + 1); | ||
const segments = destination.substring(destination.indexOf('/media')).split('/'); | ||
fs.writeFileSync(destination + '.map', JSON.stringify(result.sourceMap).replaceAll('file://' + mapRoot, '../'.repeat(segments.length - 2))); | ||
|
||
// Write the content to the destination file with the source mapping | ||
fs.writeFileSync(destination, result.css.toString().trim() + '\n/*# sourceMappingURL=' + path.basename(destination) + '.map */'); | ||
} | ||
} | ||
|
||
module.exports = { | ||
buildAsset: buildAsset, | ||
watchAssets: watchAssets, | ||
transpile: transpile | ||
} |
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,155 @@ | ||
/** | ||
* @package DPCalendar | ||
* @copyright Copyright (C) 2024 Digital Peak GmbH. <https://www.digital-peak.com> | ||
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL | ||
*/ | ||
|
||
// The needed libs | ||
const path = require('path'); | ||
const rollup = require('rollup'); | ||
const resolve = require('@rollup/plugin-node-resolve'); | ||
const replace = require('@rollup/plugin-replace'); | ||
const terser = require('@rollup/plugin-terser'); | ||
const svg = require('rollup-plugin-svg'); | ||
const vue = require('rollup-plugin-vue'); | ||
const license = require('rollup-plugin-license'); | ||
const css = require('rollup-plugin-import-css'); | ||
const urlresolve = require('rollup-plugin-url-resolve'); | ||
const util = require('./util'); | ||
|
||
async function buildAsset(root, asset, config) { | ||
try { | ||
const rollupConfig = getConfig(root, asset, config); | ||
if (Object.keys(rollupConfig.input).length === 0) { | ||
return; | ||
} | ||
|
||
// Compress and remove debug and comments | ||
rollupConfig.plugins.push(terser({ | ||
module: true, | ||
compress: { | ||
drop_console: true, | ||
drop_debugger: true, | ||
}, | ||
format: { comments: false } | ||
})); | ||
|
||
// Add the license header | ||
rollupConfig.plugins.push(license({ banner: { content: config.docBlock } })); | ||
|
||
// Create the rollup instance | ||
const bundle = await rollup.rollup(rollupConfig); | ||
|
||
// Generate code | ||
await bundle.write(rollupConfig.output); | ||
} catch (e) { | ||
console.log(e); | ||
} | ||
}; | ||
|
||
async function watchAssets(root, assets) { | ||
assets.local.forEach(async (asset) => { | ||
const rollupConfig = getConfig(root, asset, assets.config); | ||
if (Object.keys(rollupConfig.input).length === 0) { | ||
return; | ||
} | ||
|
||
// Delete the directory | ||
util.deleteDirectory(root + '/' + asset.dest); | ||
|
||
try { | ||
// Use source maps | ||
rollupConfig.output.sourcemap = true; | ||
|
||
// Watch the files | ||
const bundle = await rollup.watch(rollupConfig); | ||
|
||
bundle.on('event', (event) => { | ||
switch (event.code) { | ||
case 'START': | ||
startBundleTime = Date.now(); | ||
break; | ||
case 'BUNDLE_START': | ||
console.log(`Started to create the following bundles to ${event.output}:\n - ${Object.values(event.input).join('\n - ').replaceAll(root, '')}`); | ||
break; | ||
case 'BUNDLE_END': | ||
console.log(`Finished to create bundles ${Array.isArray(event.output) ? event.output.join(',') : event.output} in ${Date.now() - startBundleTime}ms`); | ||
break; | ||
case 'END': | ||
console.log(`Waiting for changes`); | ||
break; | ||
default: | ||
break; | ||
} | ||
}); | ||
} catch (e) { | ||
console.log(e); | ||
} | ||
}); | ||
} | ||
|
||
function getConfig(root, asset, config) { | ||
// Traverse the directory and build the assets | ||
const files = {}; | ||
util.getFiles(root + '/' + asset.src).forEach((file) => { | ||
// Files starting with an underscore are treated as imports and do not need to be built | ||
if (path.basename(file).indexOf('_') === 0 || file.indexOf('.js') === -1) { | ||
return; | ||
} | ||
|
||
files[file.replace(root + '/js/', '').replace('.js', '')] = file; | ||
}); | ||
|
||
return { | ||
input: files, | ||
output: { | ||
dir: root + '/' + asset.dest, | ||
format: 'es', | ||
entryFileNames: '[name].min.js', | ||
chunkFileNames: (chunkInfo) => { | ||
// The path segments | ||
const segments = (chunkInfo.facadeModuleId ?? chunkInfo.moduleIds[0]).split('/'); | ||
|
||
// Special handling for libs | ||
if (segments.indexOf('node_modules') !== -1) { | ||
// The root libraries name | ||
let name = 'vendor/'; | ||
|
||
// Add the package name and module | ||
name += segments.splice(segments.findIndex((p) => p === 'node_modules') + 1, 2).join('/').replace('@', ''); | ||
|
||
// Normalize the filename | ||
name += '/' + chunkInfo.name.replace('.min', '').replace('.esm', '') + '.min.js'; | ||
|
||
return name; | ||
} | ||
|
||
// Get the module folder | ||
const name = segments.at(-2); | ||
|
||
// Return the internal modules with package name as subpath | ||
return 'modules/' + (name !== 'js-modules' ? name + '/' : '') + '[name].min.js'; | ||
} | ||
}, | ||
plugins: [ | ||
replace({ | ||
preventAssignment: true, | ||
values: { | ||
'process.env.NODE_ENV': JSON.stringify('development'), | ||
'process.env.VUE_ENV': JSON.stringify('browser') | ||
} | ||
}), | ||
resolve.nodeResolve({ modulePaths: [config.moduleRoot + '/node_modules'] }), | ||
urlresolve(), | ||
svg(), | ||
vue(), | ||
css() | ||
], | ||
context: 'window' | ||
}; | ||
} | ||
|
||
module.exports = { | ||
buildAsset: buildAsset, | ||
watchAssets: watchAssets | ||
} |
Oops, something went wrong.