Webpack / ES6 dynamic import - javascript

I'm using ES6 dynamic import to load a Sass file, according to an environment variable.
It's working fine, but when I build the production directory with Webpack, all the Sass files are exported as a JS chunk in the build directory.
After some research, I finally understand that import() look for similar files with the same path (only when I put a variable in the import)
It's quite problematic, I'd like to get the correct Sass file exported, and not the others.
import(`./assets/scss/App.${brandName}.scss`)
Any idea ?

Normally, you can't do that!
Because import statement must be at the top. Thus, you cannot define the variable before import statement. Hence, you cannot utilize the variable in import statements.
But, you can trick to use like this:
import brandName from 'your_path_to_brandName_export'
import(`./assets/scss/App.${brandName}.scss`)
Update
I am not sure about dynamic import, but it might help you further. See this proposal:
<script type="module">
import * as module from './utils.mjs';
module.default();
// → logs 'Hi from the default export!'
module.doStuff();
// → logs 'Doing stuff…'
</script>
See this source for further help.
Hope, this helps!

Related

What is the final way to import es lodash modules?

So, I know there are a lot of similar questions here, I read all, as well as several web articles. Still, I cannot find a solution. I simply want to import es modules from lodash. Currently using rollup via codekit app.
Simply doing one of the following, will always end up in an empty js file:
import each from 'lodash-es';
import { each } from 'lodash-es';
import each from 'lodash-es/forEach';
import each from 'node_modules/lodash-es';
They all will end with the empty (currently compiling in iife):
(function () {
'use strict';
})();
Why?
If the function isn't used in the code in any way, it will get stripped from the production output due to a process called tree shaking. It's an optimization that looks at code imports and then eliminates any unused code as a result.
It turns out that was the case here as each wasn't used and it was imported only.

ES6 Modules - 3 ways of importing files

Hello guys i have a little question about importing files into a single .js file.
Which way is better (best practice), what's the scenario that is used for:
import './file;'
import { something } from './file'
import * as evertything from './file'
Because i see that 2 and 3 are the same thing but different syntax(maybe Syntactic Sugar).
All three do different things.
import './file;'
That loads the file, and does not import anything. This is useful if you want to initialize that module (or add some external dependency, e.g. a css file if you use Webpack).
import { something } from './file'
That just imports something from the file, therefore a bundler could optimize all other dependencies away. I'd always try to go with that instead of
import * as evertything from './file'
That imports everything from that module under a namespace, and therefore makes treeshaking more difficult (the bundler cannot optimize it well). I'd only use that if you need everything from that dependency, or if that dependency is loaded externally nevertheless (e.g. import * as React from "react").
I guess the following MDN documentation will make you clear about those things:
import - JavaScript|MDN
As far as I know, 1st method is used when you have only one default export. 2nd is used when you have multiple default exports but you don't want all of them to load and want only few of them. 3rd is the case when you want everything under a single object (which can be used similar to namespace in other programming languages).

How to access a variable from another JS file in webpack

I'm trying to implement webpack in a project, but can't seem to find a clear answer to this issue in their docs. I need to be able to access a certain variable globally from a JS file, for example:
toProps.js:
var myProp = "test";
In my entry point I do the following:
entry.js:
require('./toProps.js');
console.log(myProp);
But the variable myProp is undefined. This is an extremely simplified example, not my actual use case, but the point is that I'm working with an existing code base where there are these types of global references all over the place, but I want to implement some module and lazy loading with webpack.
How can I access the myProp variable?
Inside toProps.js:
var myProp = "test";
export default myProp;
Inside entry.js:
import myProp from './toProps.js';
From what I see, you haven't exported the variable. Therefore, it can't be an 'import' inside entry.js.
Edit 1: Learn more about exporting here.
Edit 2:
Okay, to make it a global variable, here's what I did:
Move props.js into /dist and link it inside index.html, before bundle.js, or whatever you've named the output file.
Now it's a global variable, so you don't actually need to export or import it anywhere.
To test this, I made a file called test.js, imported it into entry.js. Inside test.js is:
const logTest = () => {
console.log(myProp)
}
export default logTest;
Now inside entry.js, I invoked the function. It worked as expected and 'test' showed up in the console.
As you mentioned, your example is simplified, so this may not be viable for you. Maybe, you could move all the global variables to one file inside /dist, inside an object, as it's best not to pollute the global object.
Edit 3: Go with the answer from Jonas W. Totally forgot you could do that.
If you really need a global variable (no you dont!), use window:
window.myProp = "test";
Otherwise just export it from your file and import it everywhere you need it. That maybe adds some overhead to your code, but actually you always know where the value comes from, which makes debugging super simple.
Using webpack 4
To update this post for anyone that can read it, acctually you can use a plugin in webpack.config.js to resolve names that used in another .js files.
Take a look in https://webpack.js.org/plugins/provide-plugin/ example:
Usage: jQuery
To automatically load jquery we can simply point both variables it exposes to the corresponding node module:
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
});
Then in any of our source code:
// in a module
$('#item'); // <= just works
jQuery('#item'); // <= just works
// $ is automatically set to the exports of module "jquery"
If the source file to import belongs to maintainer, it's best to export first and import latter. Just like the answer of #Ibrahim.
I also encounter a situation to import third party source file just not using export syntax. So I think below is a solution while using webpack.
First, install exports-loader for your project.
npm install exports-loader --save-dev
Then, in your JS source file, import and use like below:
const WEBGL = require("exports-loader?WEBGL!three/examples/js/WebGL.js");
WEBGL.isWebGL2Available()
In my case, WEBGL is the inner variable I wish to import, three/examples/js/WebGL.js is the third party source file.
Hoping this is useful.

Bootstrap-table extension import in ES6

I'd like to load/import and use the Bootstrap-table extensions but no luck yet...
The basic module load is fine:
I've added with yarn to the package.json and it sits there like this:
"bootstrap-table": "^1.11.2",
In the javascript file I import it:
import BootstrapTable from "bootstrap-table";
And the usage is fine as well:
$.extend($.fn.bootstrapTable.defaults, {
filterControl: true,
showMultiSort: true
});
$('.element').bootstrapTable();
But (obviously) it doesn't pick the custom options up. How should I load the extensions from the node_modules/bootstrap-table/src/extensions directory?
in ES5 I've had to load those js files one by one, after the bootstrap-table.js. But how does it work in ES6?
Thank you!
To use named imports the package would need to use named exports, I've just taken a look at that package and it doesn't, so you can't import a single module member with the ES6 syntax:
import {Module} from 'my-package';
so you will have to reference the file directly in your node_modules folder:
import FilterControl from '/node_modules/bootstrap-table/dist/extensions/filter-control/bootstrap-table-filter-control.min.js';
It might be worth raising an issue asking the package publisher to add the named exports, which is essentially one file entry point that exports everything for you.

Javascript ES6 import without a name [duplicate]

This question already has answers here:
import module just to run it
(2 answers)
Closed 6 years ago.
I am running Webpack, Babel and Vue.js and I want to split up my entry file. Currently I have an app.js file which is the starting point to my application.
I have some bits and pieces of Code I want to put into a bootstrap.js file which I want to include in my main app.js file can I can have a clean file to start out with Vue and add components in it as I go.
Some examples of what I would want to put in my bootstrap.js file:
import messagesNL from './translations/nl';
Vue.use(VeeValidate, {
locale: 'nl',
dictionary: {
nl: {
messages: messagesNL
}
}
});
window.Vue = Vue;
So pretty much setup for plugins, global configuration, etc. I feel like this is not your typical module and I find it hard to create a module like structure for this file so I basically use this in my app.js file:
import bootstrap from './bootstrap';
Having no idea if this would work, it seems to just import everything neatly without me having done a module exports {} like syntax.
Now the bootstrap variable that I assigned to that file is unused in app.js since it's only used to require the file and my IDE kind of 'greys` it out to let me know it is unused.
Is there another syntax for this so that I don't have to assign a name to it? Is this approach ok to split up my file, or should I be doing something else?
I haven't put it into a proper module yet because then it would have it's own local scope and I would be unsure how to set up Vue with all the plugins, etc. If anybody has a better suggestion I am open to it.
Cheers.
To include a file without importing anything you can just drop the <name> from part of the statement:
import './bootstrap';
This will execute the target module without affecting the scope of the active module, but it may have side-effects such as declaring globals or modifying existing globals.
As stated in the MDN docs for Import a module for its side effects only:
Import an entire module for side effects only, without importing anything. This runs the module's global code, but doesn't actually import any values.
import '/modules/my-module.js';

Categories

Resources