Adding SASS modules to Netlify CMS custom preview breaks Gatsby - sass

Summary
The project works without issues with SASS modules.
Trying to use SASS inside src/cms/cms.js for the purposes of customizing the CMS admin preview panel breaks the project.
Using regular CSS or CSS modules works without any problem for the admin preview panel.
I've checked for this issue on GitHub, the Netlify CMS forums and documentation, Stack Overflow, and everywhere that Google has led me.
Describe the bug
My project uses Netlify CMS and Gatsby. I have no issues with SASS when working on the project. The issue only comes up when I try to use SASS inside components that I want to use as custom preview with CMS.registerPreviewTemplate() for the CMS Admin panel at http://localhost:8000/admin/.
I've setup up everything without any issues and there are no problems when I use CSS modules.
The problem is that my project uses SASS and when I just rename import * as styles from PreviewTesting.module.css to import * as styles from './PreviewTesting.module.scss' inside PreviewTesting.jsx I get this error:
ERROR Failed to compile with 1 error 6:03:26 PM
⠀
error in ./src/templates/previewTesting/PreviewTesting.module.scss
⠀
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See
https://webpack.js.org/concepts#loaders
> .previewTestingDescription {
| background-color: lightgoldenrodyellow;
| font-family: 'Montserrat-Regular', sans-serif;
Also, just adding import '../styles/global.scss' inside the src/cms/cms.js file causes the same error that prevents the build from happening.
I've tried updating and downgrading any package I could think of and this did not help. I've also tried to register the files as preview styles with CMS.registerPreviewStyle(file); and I've tried Raw CSS with https://www.netlifycms.org/docs/beta-features/#raw-css-in-registerpreviewstyle. None of these solved the issue.
To Reproduce
Steps to reproduce the behavior. For example:
Create a React component.
Import a SASS module component into the React component.
Register that component as a preview component with CMS.registerPreviewTemplate('name', PreviewTesting) inside src/cms/cms.js
An alternative way to reproduce:
Add import '../styles/global.scss' inside the src/cms/cms.js. global.scss hold regular SASS things like imports for fonts, variable and other such things.
Expected behavior
The project should run and apply the CSS styling to the preview panel at http://localhost:8000/admin/
Screenshots
Applicable Versions:
"gatsby": "^4.9.0"
"gatsby-plugin-netlify-cms": "6.25.0"
"gatsby-plugin-sass": "5.25.0"
"netlify-cms-app": "^2.15.72"
"sass": "1.49.9"
"gatsby": "^4.9.0" (updated to the latest version "4.25.1")
Node.JS version:
Did not work on v16, updated to v18.12.1, still does not work.
CMS configuration
collections:
- name: "name"
label: "names"
label_singular: "name"
description: >
Test
create: true
slug: "{{category}}-{{slug}}"
fields:
- { name: title, label: Title }
- { name: subtitle, label: Subtitle, required: false }
Additional context
Any help would be very appreciated.

A friend of mine provided me with a solution:
The plugin order in gatsby-config.js actually matters in this case. gatsby-plugin-sass must come before gatsby-plugin-netlify-cms
The plugin segment in gatsby-config.js should look like this:
{
resolve: 'gatsby-plugin-sass',
options: {
additionalData: '#use "/src/styles/global" as *;',
sassOptions: {
includePaths: ['src/styles'],
},
},
},
{
resolve: 'gatsby-plugin-netlify-cms',
options: {
modulePath: `${__dirname}/src/cms/cms.js`,
},
},

Related

How to build ckeditor5 balloon block from source?

There are five ckeditor5 ready-made builds available: classic, inline, balloon, balloon-block and document. I would like to use the balloon-block layout, but I want to build it from source (as is recommended) for integration into my Vue 2.x app (with webpack and Vue CLI 3). The docs for building from source use the classic editor as an example, and instead of using the pre-built package #ckeditor5/ckeditor5-build-classic, it says to import the source package #ckeditor5/ckeditor5-editor-classic and use that as a base to which you can add all the plugins you want.
The balloon layout has its own source package #ckeditor5/ckeditor5-editor-balloon which presumably can be used similarly, but I can't find any source package for balloon-block. If I'm supposed to use the ...editor-balloon package as a base, are there any docs I can use that will show me how to build my own balloon-block from source?
I've just learned that the hidden toolbar accessed from the gutter is actually a plugin calle BlockToolbar, so presumably I do just have to use the editor-balloon package as the source base and include/configure that plugin. If someone else doesn't provide a more complete example with sample config, I'll post an answer with my own solution when I have something. In the meantime, the docs here for the block toolbar plugin has lots of info on how to set it up.
You need to install the package '#ckeditor/ckeditor5-ui', which should already be a dependency of '#ckeditor/ckeditor5-editor-balloon' itself and import the plugin 'BlockToolbar' and use it in your 'create()' method call. Like so:
import BalloonEditor from '#ckeditor/ckeditor5-editor-balloon/src/ballooneditor';
import { BlockToolbar } from '#ckeditor/ckeditor5-ui';
import Essentials from '#ckeditor/ckeditor5-essentials/src/essentials';
import Paragraph from '#ckeditor/ckeditor5-paragraph/src/paragraph';
BalloonEditor
.create(document.querySelector('#editor'), {
plugins: [BlockToolbar, Essentials, Paragraph], // BlockToolbar added here!
toolbar: ['bold', 'italic'],
blockToolbar: ['heading', 'paragraph', 'heading1', 'heading2', 'bulletedList', 'numberedList'],
});

Prismic images don't load in vue site and create runtime/compiler error

I integrated the prismic.io headless cms into my vuetify project and have been able to render content from key text fields I created in my prismic repository into the project, but I haven't been able to load images. When I view the page in a browser I get the following console error:
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
found in
--->
at /Users/jbdebiasio/dev/prismic-vue/src/components/Image.vue
When I view the image with inspect element it shows the following markup:
<!--function (a, b, c, d) { return createElement(vm, a, b, c, d, true); }-->
What does this mean and what do I need to do to render images properly? I tried updating my app instance but observed no changes.
My company recently ran into the same issue, and it's because of the way the Prismic Vue package is built.
It's caused by Prismic not using render functions, and instead requires the template compiler to build their components at runtime.
You're going to need to add the full build of Vue, which includes the template compiler
The following example works if the project was made with the Vue CLI
// vue.config.js
module.exports = {
// Will merge all properties with the default web pack config
configureWebpack: {
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
}
}
}
}
More info on this here
Vue CLI config here here
This solution is obviously just a bandaid, and the real problem needs to be addressed by Prismic. See this pull request.

NativeScript adding xml namespace on Page tag

I'm new to NativeScript. I have created a new project using the Angular Blank template. The navigation is done using page-router-outlet. I want to include a xmlns attribute on the page level. As far as i can see and understand the entire code is rendered inside a global page attribute. I've seen that I can modify the page properties by injecting the Page in a component and changing it's properties, but how can I do this for xmlns?
Best regards,
Vlad
To register a UI component in Angular based application you should use registerElement and not XML namespaces (which is a concept used in NativeScript Core). Nowadays most plugin authors are doing this job for you, but still, some of the plugins are not migrated to use the latest techniques so in some cases, we should manually register the UI element.
I've created this test applicaiton which demonstrates how to use nativescript-stripe in Angular. Here are the steps to enable and use the plugin.
Installation
npm i nativescript-stripe --save
Register the UI element in app.module.ts as done here
import { registerElement } from "nativescript-angular/element-registry";
registerElement("CreditCardView", () => require("nativescript-stripe").CreditCardView);
Add the following in main.ts as required in the plugin README
import * as app from "tns-core-modules/application";
import * as platform from "tns-core-modules/platform";
declare const STPPaymentConfiguration;
app.on(app.launchEvent, (args) => {
if (platform.isIOS) {
STPPaymentConfiguration.sharedConfiguration().publishableKey = "yourApiKey";
}
});
Use the plugin in your HTML (example)
<CreditCardView id="card"></CreditCardView>

Laravel, Datatable, Composer and Webpack : Good practices to allow developpers to customize my library in their projects

To set the context I am creating a CRUD application for Laravel. It is installed via composer and the sources are therefore in the vendor/organization/package directory.
In my project, I use Datatable. So I use Laravel Mix to compile my sources and a command line allows to copy JS and CSS compiled files into the public directory of the Laravel Host application.
I would like however that the developers who will use my library can customize the display of some Datatable cells. To do this you must use Datatable's createdCell configuration.
$('#example').dataTable( {
"columnDefs": [ {
"targets": 3,
"createdCell": function (td, cellData, rowData, row, col) {
if ( cellData < 1 ) {
$(td).css('color', 'red')
}
}
} ]
});
The problem is that the JS sources of my project are already compiled...
For the moment I found a temporary solution that consists in leaving the JS sources in vendor/organization/package but copying the webpack.mix.js configuration into the Host application and asking the developers to compile themselves. The problem is that all JS dependencies must also be installed and it doesn't take very seriously to force the developers to compile sources before being able to use my library.
What are good practices to achieve this objective?
The following source may help, but I confess I don't know how to apply it to Laravel:
How to bundle vendor scripts separately and require them as needed with Webpack?
Thank you for your help.

How To Configure TypeScript and Require in Visual Studio 2017

Even though this talks about VueJS. I suspect it will work with any other JavaScript language like Angular or React as well.
I have been learning Vue.js and loving it. Knowing I have a larger application on the way and the fact that I have wanted to start using TypeScript. Now seems like the time to do so. I have a firm grasp on Vue at this point but can not find any documentation (over 2 weeks of finding the exact, MINIMUM requirements) on how to setup TS and actually get it to run.
Here is an example of some HTML and Vue code that works with using just script tags and normal JavaScript.
HTML
<div id="app">
<h4>{{ Value }}</h4>
</div>
#section Scripts {
<script src="~/lib/vue/vue.js"></script>
<script src="~/js/test.js"></script>
}
JavaScript - test.js
var app = new Vue({
el: "#app",
data: {
Value: "Hello there"
}
});
This works and produces Hello there on the page.
Configuring TypeScript
This seems straight forward, I have a TypeScripts folder below my js folder where the "source" .ts files will be. The output files will be in the js folder as .js files. Here is my tsconfig.json located in the TypeScripts folder:
{
"compileOnSave": true,
"compilerOptions": {
"noEmitOnError": true,
"noImplicitAny": false,
"outDir": "../",
"removeComments": false,
"sourceMap": true,
"target": "es5",
"module": "amd" // <-- Should this be used?
},
"exclude": [
"node_modules",
"wwwroot"
]
}
This works and I do get .js files each time a save the .ts files.
However, now I want to incorporate Vue into the .ts using it in ways I have seen in videos as well as code online. The following code compiles without errors:
JavaScript - ES6 - test2.ts
const Vue = require("vue")
const app = new Vue({
el: "#app",
data: {
Value: "Hello there"
}
})
Now I update the HTML to the following:
HTML
<div id="app">
<h4>{{ Value }}</h4>
</div>
#section Scripts {
<script src="~/js/test2.js"></script>
}
I reload the page and all I get is the {{ Value }} markup. Plus the JavaScript error: Uncaught ReferenceError: require is not defined.
That seems simple enough, I figure I just add the following line to the Scripts section and remove the single reference to the test2.js file:
#section Scripts {
<script src="~/lib/require.min.js" data-main="/js/test2.js"></script>
}
Reload and now I get: Uncaught Error: Module name "vue" has not been loaded yet for context: _. Use require([]) which references this but that code now seems to diverge from what the .ts file should look like.
The ES6 Test2.ts file seems to be the way people code. The way it wants me to write the require statement in the link above seems far more verbose and does not show up in any code samples I have seen. So I must be missing something. If it helps, the Vue and Require downloads have come from my package.json (npm) file which looks like this:
"devDependencies": {
"#types/node": "^9.4.7",
"requirejs": "^2.3.5",
"vue": "^2.5.16"
...
}
And my bundleconfig.json which puts them in the wwwroot/lib folders where they should go.
{
"outputFileName": "wwwroot/lib/require.min.js",
"inputFiles": ["node_modules/requirejs/require.js"]
},
{
"outputFileName": "wwwroot/lib/vue/vue.js",
"inputFiles": [ "node_modules/vue/dist/vue.js" ]
}
I have to believe I am so close to getting it. Being able to write code in the more modern ES versions is great. I have just not been able to find the right piece of the puzzle to fit it all together.
The main problem above is because in the first "plain JavaScript" example, you are not using modules at all. You are loading the Vue library directly in your page, which creates the global Vue object, and then your script is global (i.e. not a module) and references the Vue object directly.
For the test2.ts file, you mention this is ES6, but you then 'require' in the Vue library. This means the code is now attempting to use modules, but CommonJS modules, not ES6 modules. (Where you would write something like import Vue from "vue"). This means it would require a loader at runtime (e.g. the require.js library you are trying to use), which could work if configured correctly, but generally you'd want something like WebPack to package up Vue.js and your code into a standalone bundle the page loads at runtime.
Note: Edited paragraph below
I've created a sample ASP.NET Core project showing how to configure TypeScript and WebPack to generate a bundle per page using the global Vue.js object via a script tag. I've put an extensive readme on it to explain all the workings. You can see it at https://github.com/billti/SimpleVueApp . If you have further feedback, I'll continue to update it to make it better/clearer.
That said, as you get deep in Vue there is one Visual Studio limitation to be aware of. Currently there is no rich support for .vue files (known in the docs as "single file components"). What I mean by "rich support", is that these files have a certain context that we don't infer right now to provide good IntelliSense (i.e. completion lists, errors, tooltips, etc.). Also, HTML files in Visual Studio (which is what you would open a .vue files as) also only support plain CSS in <style> tags, and plain JavaScript in <script> tags currently, whereas with the right Vue and WebPack setup you can do things like write LESS code directly in your style tags, and write TypeScript directly in your script tags. My team is looking at this currently and hoping to improve this in the near future.
Let me know if any of that isn't clear. Happy to help further.

Resources