Skip to content

feat: migrate vue-cli v4 -> v5 and using VueJS V2 #1

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

Merged
merged 1 commit into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = {
'@vue/airbnb',
],
parserOptions: {
parser: 'babel-eslint',
parser: '@babel/eslint-parser',
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
Expand Down
6 changes: 3 additions & 3 deletions .stylelintrc.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "stylelint-config-standard",
"plugins": [
"stylelint-scss"
"extends": [
"stylelint-config-standard-scss",
"stylelint-config-recommended-vue/scss"
],
"rules": {
"at-rule-no-unknown": null,
Expand Down
37 changes: 1 addition & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# patternlab-node-vuecli
My first try to make patternlab node V3 with Twig, Vue-Cli-Service and Webpack work together.
My first try to make patternlab node with Twig-PHP, Vue-Cli-Service and Webpack work together.

Thank you, https://github.com/Comcast/patternlab-edition-node-webpack for your inspiration!!!

Expand All @@ -13,43 +13,8 @@ The complete process is coupled to the Vue-Cli-Service - this is not a Webpack o

---

For me, the important things (which work) are:
<small>Currently i did not do a lot of tests due to heavy debugging :)</small>

* Start Dev with `vue-cli-service serve`
* Webpack Dev Server runs Patternlab with Twig Templates and not only the Vue public HTML document
* HMR for JS and CSS
* Code Splitting / Vue Async Components loading seams to work
* Import Twig files in Twig files

Currently not working, but nice to have:
* Delete, move or rename of patterns will not correctly recomplile / remove them from the "frontend"
* They will be gone after restart of `serve` task

---

## Patternlab Node
https://github.com/pattern-lab/patternlab-node

## Vue CLI
https://github.com/vuejs/vue-cli

Used Vue settings to create project:
```
{
"useConfigFiles": true,
"plugins": {
"@vue/cli-plugin-babel": {},
"@vue/cli-plugin-router": {
"historyMode": false
},
"@vue/cli-plugin-eslint": {
"config": "airbnb",
"lintOn": [
"save"
]
}
},
"cssPreprocessor": "node-sass"
}
```
126 changes: 18 additions & 108 deletions buildScripts/PatternlabPlugin.js
Original file line number Diff line number Diff line change
@@ -1,133 +1,44 @@
const globby = require('globby');
const minimatch = require('minimatch');
const { resolve, join } = require('path');
const { resolve } = require('path');
const fs = require('fs-extra');
const { warn, done } = require('@vue/cli-shared-utils');
const patternlabCore = require('@pattern-lab/core');

const VueService = process.VUE_CLI_SERVICE;

const plConfig = require('../patternlab-config.json');
const contentBaseDir = join(VueService.context, plConfig.paths.public.root);

const contentBaseDir = resolve('./', plConfig.paths.public.root);
const pluginName = 'PatternlabPlugin';

class PatternlabPlugin {
constructor() {
this.pluginName = 'PatternlabPlugin';
this.startTime = Date.now();
this.prevTimestamps = new Map();
this.patternlab = patternlabCore(plConfig);
this.PlPatternPath = resolve(VueService.context, plConfig.paths.source.patterns);
this.firstRun = true;
}

this.buildPatternlab();
apply(compiler) {
// fix html webpack plugin error child compilation failed
// due to missing index.html inside the content base dir
// because patternlab build not finished before html plugin init :(
// create index.html
fs.ensureFileSync(join(contentBaseDir, 'index.html'));
}

apply(compilation) {
this.initHooks(compilation);
}

initHooks(compilation) {
if (compilation.hooks) {
compilation.hooks.afterCompile.tap(this.pluginName, this.addPatternLabFiles.bind(this));
compilation.hooks.watchRun.tap(this.pluginName, this.watchRun.bind(this));
}
}
fs.ensureFileSync(resolve(contentBaseDir, 'index.html'));

addPatternLabFiles(compilation) {
const patternFiles = this.getPatternlabFiles();
patternFiles.forEach(item => {
compilation.fileDependencies.add(item);
});

if (compilation.contextDependencies && !compilation.contextDependencies.has(this.PlPatternPath)) {
compilation.contextDependencies.add(this.PlPatternPath);
}
}

getPatternlabFiles() {
const allWatchFiles = this.getWatchFileGlobs();

const files = [];
allWatchFiles.forEach(globPath => {
const patternFiles = globby
.sync(globPath);
patternFiles.forEach(item => {
files.push(item);
});
});

return files;
}

getWatchFileGlobs() {
const supportedTemplateExtensions = this.patternlab.getSupportedTemplateExtensions();
const templateFilePaths = supportedTemplateExtensions.map(
function (extension) {
return `${plConfig.paths.source.patterns}**/*${extension}`;
}
);

// pattern lab watch file globs
const watchFiles = [
...templateFilePaths,
`${plConfig.paths.source.patterns}**/*+(json|md|yaml|yml)`,
`${plConfig.paths.source.data}**/*+(json|md|yaml|yml)`,
`${plConfig.paths.source.meta}**/*`,
`${plConfig.paths.source.annotations}**/*`
]
.map(el => VueService.context + (el.startsWith('.') ? el.substr(1) : el));

return watchFiles;
}

matchesWatchFileGlob(paths = []) {
const globs = this.getWatchFileGlobs();
let matches = [];
for (let globIndex = 0; globIndex < globs.length; globIndex++) {
matches = minimatch.match(paths, globs[globIndex]);
if (!!matches.length) {
break;
}
}

return !!matches.length;
}

watchRun(compilation, callback) {
const changedFiles = Array.from(compilation.fileTimestamps.keys()).filter(
watchfile => {
return (
(this.prevTimestamps.get(watchfile) || this.startTime)
< (compilation.fileTimestamps.get(watchfile) || Infinity)
);
compiler.hooks.done.tap(pluginName, () => {
if (this.firstRun) {
this.firstRun = false;
this.buildPatternlab();
}
);

const hasChangedPLSourceFiles = !!changedFiles.length && this.matchesWatchFileGlob(changedFiles);
const removedFiles = Array.from(compilation.removedFiles);
const hasDeletedPLSourceFiles = !!removedFiles.length && this.matchesWatchFileGlob(removedFiles);

if (hasChangedPLSourceFiles || hasDeletedPLSourceFiles) {
this.buildPatternlab();
}

this.prevTimestamps = compilation.fileTimestamps;

if (callback) { callback(); }
});
}

buildPatternlab() {
const { cleanPublic } = plConfig;
const options = { 'cleanPublic': cleanPublic };
const options = {
cleanPublic,
watch: true,
};

if (!this.patternlab.isBusy()) {
try {
this.patternlab.build(options)
.then(r => {
.then(() => {
done('Patternlab build complete');
})
.catch((error) => {
Expand All @@ -138,7 +49,6 @@ class PatternlabPlugin {
}
}
}

}

module.exports = PatternlabPlugin;
38 changes: 28 additions & 10 deletions buildScripts/patternlabWebpackPlugins.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
/* eslint-disable no-param-reassign */
const { join, resolve } = require('path');
const PatternLabPlugin = require('./PatternlabPlugin');

const { getIfUtils } = require('webpack-config-utils');
const { join } = require('path');
const VueService = process.VUE_CLI_SERVICE;

const plConfig = require('../patternlab-config.json');
const { ifDevelopment } = getIfUtils(process.env.NODE_ENV);
const contentBaseDir = join(VueService.context, plConfig.paths.public.root);

const ifDevelopment = process.env.NODE_ENV !== 'production';
const contentBaseDir = resolve('./', plConfig.paths.public.root);

/**
* update and add plugins
* @param config
*/
const patternlabVuePluginConfig = (config) => {
config
.plugin('html')
.tap(args => {
.tap((args) => {
args[0].template = join(contentBaseDir, 'index.html');
return args;
});

if (ifDevelopment()) {
config.plugin('patternlabplugin').use(PatternLabPlugin)
if (ifDevelopment) {
config.plugin('patternlabplugin')
.use(PatternLabPlugin)
.before('html');
}
};

config.devServer.contentBase(contentBaseDir);
/**
* Change dev server directory in configureWebpack
* @param config
*/
const patternlabVueWebpackConfig = (config) => {
if (!config.devServer) {
config.devServer = {};
}
if (!config.devServer.static) {
config.devServer.static = {};
}
config.devServer.static.directory = contentBaseDir;
};

exports.patternlabVuePluginConfig = patternlabVuePluginConfig;
exports.patternlabVueWebpackConfig = patternlabVueWebpackConfig;
Loading