If I'm using webpack or browserify, what's the exact process to be able to import only the necessary modules from jQuery that are listed here?
import {core, dimensions} from 'jquery'
doesn't work.
You can import modules from jQuery's src directory, like so:
import core from 'jquery/src/core';
import dimensions from 'jquery/src/dimensions';
The jQuery sources use asynchronous module definitions to load modules internally (AMD), so you have to use a module bundler to use it. Webpack would be a good choice for this, it supports AMD out of the box.
Related
Right now I pull in all my own es6 modules and create a bundle using Rollup.
Recently I started using VueJS, which now has an ES6 Module which can be pulled in just like my own modules. Rollup does some treeshaking on it, but I don't know if that is a very good idea? I don't know what it is doing, so I would rather it does nothing!
Instead I just add vue at the end of my HTML:
<script src="dist/bundle.js"></script>
I love the convenience of having everything as one bundled file, but should I really treeshake the entire Vue app, is there a command in Rollup that I can not treeshake just this one module?
EDIT
I have found the --external option, which seems good as it would just keep the import for vue and bundle the rest, but it does not seem to work!
When I use rollup --format=iife --external=../node_modules/vue/dist/vue.esm.browser.js --file=dist/bundle.js -- src/main.js it says Error: Could not resolve '../node_modules/vue/dist/vue.esm.browser.js' from src/app.js.
In my main.js it has import Vue from '../node_modules/vue/dist/vue.esm.browser.js; which works fine for the app. I want to make Vue an external, but it won't work!
To prevent Rollup from treeshaking a particular module, you can simply import it blindly (instead of a part of it), so that Rollup thinks the module performs some side effect:
import 'vue'
Of course you can still import some bits in parallel, so that you can rename the default export for example:
import 'vue'
import Vue from 'vue'
As for your --external option, you probably just need to wrap the path value with quotes:
--external='../node_modules/vue/dist/vue.esm.browser.js'
Note that you should probably switch to Rollup configuration file (instead of CLI options) to make your life easier. You will also be able to use rollup plugins, e.g. rollup-plugin-alias to manage the exact location of the Vue file you want to use.
I've around 20 jsx files with the few repeated imports like :
import React from 'react';
import { Form } from 'formsy-react';
import AppActions from '../../utils/actions/app-actions';
import store, {formStore} from '../../utils/stores/stores';
import AppConstants from '../../utils/constants/app-constants';
which cause my bundle.js weight more than 1.7 Mb even after minification.
Is there any possiblity to import these modules from any where else so that I don't need to import these again and again.
I think there is a misunderstanding here between Webpack, ES6 and a module.
Webpack is going to analyse your javascript code and detect the dependencies, based on that it will include the modules you need in your bundle, there is no duplicate there, every module is added only once in the proper order to resolve the dependencies while avoiding duplicates of code.
ES6 import export syntax convention requires to define the imports you need in every file that requires them, so browsers or tools like Webpack can properly detect dependencies and only use files they need.
1.7 Mb can be considered as a big file for a web page, but with a proper caching/minification it can be loaded instantly
What is the current recommended practice for converting a library written in TypeScript to ES5?
JSPM documentation seems to be geared toward web apps (i.e. with jspm bundle-sfx).
All the articles I can find on Google seems to be assuming a web app workflow rather than a library workflow.
My projects have the following setup:
It depends on react, flux and jquery, all installed through jspm and are properly configured in config.js
The source .tsx/.ts files are located in a src/ tree, along with their corresponding transpiled .js files
I am able to create a bundle with jspm bundle, however, this still requires the end user of my library to be using SystemJS
What I want is to bundle the entire tree under src/ into a single file without libraries such as react or jquery. How can I do this?
So far I've tried jspm bundle src/<MY_MAIN.js> - react - jquery <OUT.js> this works, but user still need a module loader to interact with exported symbols in MY_MAIN.js. I would also like to provide users with an option to manually import my library with <script> tags. self-executed bundles do not seem to work. No symbol is accessible globally once loaded through the <script> tag and I cannot exclude the framework code.
There are basically three approaches that I want to highlight, targeted at different end-user workflows
1. the <script/> tag approach
Here, create an entry .ts file that exports the main symbols of the library like so:
// Main.ts
import {MyLib} from "./components/MyLib";
import * as React from "react";
import * as ReactDOM from "react-dom";
/**
* browser exports
* note, typescript cannot use interfaces as symbols for some reason, probably because they are not emitted in the compiled output
* running `jspm bundle-sfx` results in the code here being accessible in <script /> tag
*/
(function (window) {
window.MyLib = MyLib;
window.React = window.React || React;
window.ReactDOM = window.ReactDOM || ReactDOM;
})(typeof window !== "undefined" ? window : {});
then run jspm bundle-sfx Main.js my-lib.sfx.js, the same works for browserify, except we have to use commonjs style require() instead of ES6 style import
2. Concat & Minify src files through regular gulp/grunt
this should just be the good old workflow we are all familiar with
3. Assume ES6 compatibility for apps that will use the library
Distribute the code as ES6/TS along with .d.ts and assume the user will also use jspm/system or eventual ES6 module loader approach to load your module
How can I import a static url using webpack:
index.js
import 'http://google.com/myscript.js'
It's really unclear what you're trying to do, but in general you have a few options.
Pre-download the script or install it via NPM. This probably is the preferred way to deal with external dependencies. Once it is local you can easily import or require it like any other module.
If it absolutely must be loaded dynamically you will need a 3rd party module such as https://www.npmjs.com/package/scriptjs which can easily download 3rd party modules at runtime and block the execution of the rest of the script until it has been parsed.
Use a <script> tag and include it on your page. This only works if it's a general dependency that can be loaded before everything else (maybe for a polyfill or a library you depend on everywhere like jquery.)
I hope that helps!
This webpack issue says you can use this comment to allow the import to just work. Though this is only dynamic import not static.
import(/* webpackIgnore: true */ "https://example.com");
First seen here https://stackoverflow.com/a/69951351/4619267
import is es6. With es5 and webpack, use require, or better wrap your JS files with AMD/UMD.
Is anybody able to explain the difference between a simple import and a System.import statement of the ES6 Module Loader (or Polyfills like System.js, Webpack etc.)
Something like
System.import('https://code.jquery.com/jquery.js').then();
seems to be possible, as well as a simple
import 'jquery';
Is System.import the only possibility to have a callback after the import statement?
You can use the System.import inside <script> tags where import aren't supported, and you can also load modules conditionally.
So you can programmatically import a module, via an API based on ES6 promises, in addition of the declarative syntax for working with modules that is the ES6 import.