I am trying to configure Monaco as a webcomponent (using vite's lit-ts template) that edits a single, custom language and without lots of Monaco's extra features. (I then want to copy the output to include using a script tag in my main project's index.html)
In my main file I have
import {monaco} from "./customMonaco";
// add support for the 1 custom language I do want
import "./mix.contribution.js";
In customMonaco.ts I have
import "monaco-editor/esm/vs/editor/browser/viewParts/contentWidgets/contentWidgets.js";
import "monaco-editor/esm/vs/editor/browser/viewParts/lineNumbers/lineNumbers.js";
import "monaco-editor/esm/vs/editor/browser/viewParts/lineNumbers/lineNumbers.css";
import "monaco-editor/esm/vs/editor/browser/viewParts/linesDecorations/linesDecorations.js";
import "monaco-editor/esm/vs/editor/browser/viewParts/linesDecorations/linesDecorations.css";
import * as monaco from "monaco-editor/esm/vs/editor/editor.api.js";
export {monaco};
But when I build this I am still getting all the language files.
My vite config is
export default defineConfig({
build: {
lib: {
entry: 'src/rmx-monaco.ts',
formats: ['es']
},
rollupOptions: {
external: /^lit/,
// output: {
// manualChunks: undefined,
// inlineDynamicImports: true,
// entryFileNames: "[name].js",
// // Prevent vendor.js being created
// // prevents adding cache busting
// chunkFileNames: "assets/[name].js",
// assetFileNames: "rmx-monaco.[ext]",
// },
}
}, server: {port: 5000}
})
and next I will uncomment the output section so as to get just 1 js file, but I don't want it to include language support
Related
I am trying to change the default webpack loader for SVG files in Gatsby JS. I want to use the 'svg-url-loader' instead of the default 'url-loader'. I have installed it, and it works fine with webpack-inline-loaders.
But to avoid repeating the process, I decided to use the onCreateWebpackConfig Node API to change the loader for the SVG files. So I added the below code in the gatsby-node.js file.
exports.onCreateWebpackConfig = ({
stage,
getConfig,
rules,
loaders,
plugins,
actions,
}) => {
actions.setWebpackConfig({
module: {
rules: [
{
test: /\.svg/,
use: {
loader: "svg-url-loader",
options: {
limit: 4096,
iesafe: true,
},
},
},
],
},
});
};
But the website is now not displaying any SVG image but alt text. This is because the src attributes of those IMG tags are using a faulty base64 encoded image and not the UTF8 encoded SVG XML tag.
The console is not logging any errors. I have also tried creating a local plugin at the /plugins dir, but it doesn't work. I am developing my site on my local machine and building it using Gatsby Cloud. The problem exists in both places.
Here's the link to a minimal repro.
The problem here is that to use a custom loader in any framework, you have to disable the default loader first. Then you'll be able to add your custom loader. So, first, you have to disable the default, 'url-loader' and then set the 'svg-url-loader' for SVG files.
exports.onCreateWebpackConfig = ({
stage,
getConfig,
rules,
loaders,
plugins,
actions,
}) => {
const config = getConfig();
config.module.rules.find(
(rule) =>
rule.test &&
rule.test.toString() ===
"/\\.(ico|svg|jpg|jpeg|png|gif|webp|avif)(\\?.*)?$/"
).test = /\.(ico|jpg|jpeg|png|gif|webp|avif)(\?.*)?$/;
config.module.rules.push({
test: /\.svg/,
use: {
loader: "svg-url-loader",
options: {
limit: 4096,
iesafe: true,
},
},
});
actions.replaceWebpackConfig(config);
};
I want a custom schematic that will create a page in my application. To do this, I want to use the existing core schematics to create a routing module, then create a component in that module to display my page content, and finally wire everything together. It's the "wire everything together" that has me stumped. I can't find clear guidance on the "right" way to to this. Should I:
a) directly modify the existing files that the "module" and "component" schematics created? (I don't know how to do that)
b) use templates to somehow merge the modifications into the files? (I don't know how to do this either)
Below is the index.ts file for my page schematic as of now. What I don't know how to do is commented by "TODO" towards the end.
Please help!
import {
externalSchematic,
Rule,
SchematicContext,
Tree,
chain,
} from '#angular-devkit/schematics';
export function page(options: any): Rule {
const name = options.name;
return chain([
// create module for this page
externalSchematic('#schematics/angular', 'module', {
name: `pages/${name}`,
routing: true
}),
// create simple component to display in this page
externalSchematic('#schematics/angular', 'component', {
name: `pages/${name}/${name}`,
routing: true
}),
// add component to routing module
(tree: Tree, _context: SchematicContext) => {
// TODO 1: import new component into routing module
// e.g. import { MyPageComponent } from "./my-page/my-page.component";
// TODO 2: add component to routes
// const routes: Routes = [{ path: '', pathMatch: 'full', component: MyPageComponent }];
return tree;
},
]);
}
I have installed AnimeJS with the following commands in my Ionic 4 project:
npm i animejs --save
npm i #types/animejs --save
I then attempted to reference it by using:
import * as anime from 'animejs'
Doing the above gives me the following error when calling anything from animejs:
Error: Uncaught (in promise): TypeError: Object is not a function
(near '...animejs__WEBPACK_IMPORTED_MODULE_1__...')
However, if I import by referencing the anime.js within the node_modules directory, everything will work just as expected. I thought by installing #types/animejs this would allow me to use just a simple import * as anime from 'animejs' without having to directly reference the file within the node_modules directory.
Why can I import using the node_modules folder but not import * as anime from 'animejs'
After importing I call it like so:
openModal(modalPage) {
// Define modal to open
switch (modalPage) {
case 'login' : {
modalPage = LoginPage;
break;
}
case 'register' : {
modalPage = RegisterPage;
break;
}
}
// Open modal
this.modalCtrl.create({
component: modalPage,
cssClass: 'intro-modal',
showBackdrop: true,
enterAnimation: this.animations.modalEnter
}).then(modal => {
// Hide intro buttons
anime({
targets: ['.intro-buttons'],
translateX: '-100%',
duration: 150,
easing: 'linear'
});
// Animate slide back
modal.onWillDismiss().then(() => {
anime({
targets: ['.intro-buttons'],
translateX: '0%',
duration: 150,
easing: 'linear'
});
});
// Present the modal
modal.present();
});
}
Update your import to the following:
import anime from 'animejs'
This will import the default export from animejs which is actually a function that take the params/object that you are attempting to pass.
Here is an example in action showing the import and passing the expected object to anime() without the error triggering.
With your existing import * as anime, if you log anime, you'll see a property default of that object that is the actual function you are needing. Also you will see that import is bringing in various other properties/functions including penner, stagger, and timeline. You were simply targeting the wrong property with your previous import.
Hopefully that helps!
I just created a published npm package for the first time, called "Foo". I am trying to consume it in a typescript project, but none of the tutorials about how to declare modules with custom typings, are clear to me. Here are the key parts of the npm package:
news.ts
import { tdsRequest } from "../common/request";
function articles(uri) {
return tdsRequest({ method: "GET" }, uri).then(returnData => console.log(returnData, "return data"));
}
export {
articles,
};
main.ts (main export)
import * as news from "./services/news";
export default {
news
};
in the typescript project that's consuming the npm package:
import { news } from "Foo";
and in the typings file ( Foo.d.ts ) I did:
declare module "Foo" {
export {
news: Object,
};
}
I get the following errors: cannot find module news and Cannot export 'Object'. Only local declarations can be exported from a module.
You are mixing default and named exports.
You can do default export style -
main.ts:
import * as news from "./services/news";
export default {
news
};
ts project import:
import foo from "Foo";
const {news} = foo;
foo.d.ts:
declare module "Foo" {
export default {
news: Object,
};
}
Or you can do named exports:
main.ts:
import * as news from "./services/news";
export {
news
};
ts project import:
import {news} from "Foo";
foo.d.ts:
declare module "Foo" {
export const news: Object;
}
But more importantly, you should add declaration: true to your compilerOptions in tsconfig.json in your npm library.
This will generate the d.ts file for you and will save you lots of work. Then, you need to add in package.json a filed called types that will point to the main.d.ts file that will be generated for you. This will allow any project using your library + typescript to use the generated types automatically.
I am going thru a book tutorial to learn TypeScript and AngularJS 2.0:(Become_a_Ninja_with_Angular2).
At some point it explains how to make your own Pipe and goes thru an implementation of moment.js.
In the folder where my project is located I do in CLI: npm install moment
(FYI: The book also tells to do typings install --save --ambient moment-node, but that throws an error even if I change --ambient by --global, also this error happens to not be a problem to use moment.js as the rest of the code I describe below runs).
Then, as a result of previous CLI, it creates under my project folder: [my project folder]\node_modules\moment
Then in [my project folder]\main.html, I have a <script> tag with: `
<script>
System.config({
defaultJSExtensions: true,
map: {
... [plenty of stuff starting with #angular]..
'#angular/platform-browser-dynamic':'node_modules/#angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'rxjs': 'node_modules/rxjs',
'moment':'node_modules/moment/moment'
}
});
System.import('main');
</script>
My custom Pipe looks like this:
import { PipeTransform, Pipe } from '#angular/core';
import * as moment from 'moment';
import 'moment/../locale/fr';
#Pipe({name: 'fromNow'})
export class FromNowPipe implements PipeTransform {
transform(value,args){
let mydate = moment(new Date(value));
console.log(moment.locales());
return mydate.fromNow();
}
}
As you can see in my custom pipe code, to access the locale 'fr', I had to add import 'moment/../locale/fr (what I found by looking at already existing solution on StackOverflow). If this tag was not implemented I had access to 'en' only. Which means that adding other languages will require to add import 'moment/../locale/[the locale I want available].
Anyone has any ideas how to have all the locale from the lib moment.js with just the single import * as moment from 'moment'; statement?
PS: And I added to [My project folder]\app.module.ts:
import { FromNowPipe } from './custom_pipes/fromnow.pipe';
...
#NgModule({
...
declarations: [...,FromNowPipe],
...
})
...
And somewhere in one of my component I have:
[#Component({
selector: 'ns-mycomponent',
template:`
.. <div>{{ '2016/05/01'|fromNow }}</div>..
`
})
I found a workaround:
Based on what I wrote in the question, in [my project folder]\main.html:
System.config({
defaultJSExtensions: true,
map: {
...
}
});
I substitued: 'moment':'node_modules/moment/moment' with 'moment':'node_modules/moment/min/moment-with-locales.min.js'
In my Pipe file I just kept: import * as moment from 'moment';at the beginning of the file and it works: all languages are available.