problem
I use <script> to import index.bundle.js which bundled by webpack5 in a HTML.But I failed.
option file
//webpack.config.js
const path = require('path');
module.exports = {
entry: {
index: '/src/index.ts'
},
output: {
path: path.join(__dirname, 'dist'),
library: 'test',
libraryTarget: 'umd',
}
}
//index.ts
export function mount() {
console.log("mount")
}
//html
<script src="dist/index.js"></script>
<script>
console.log(window.mount());
</script>
error
Uncaught TypeError: window.mount is not a function
code
I have checked the official documentation.But I can't find answer.
my code is here
use
yarn
npm run build
then open the index.html,you can find the error.
Using the config you currently have (which is not putting them on the root window object), you can access your functions with window.test.mount(), because that's what you have in library in the webpack config.
If you want to put these functions on the root window object, you'd need to do that in your code:
export function mount() {
console.log("mount")
}
window.mount = mount
// etc.
You can see this by checking out dist/index.js (dropping it in the Prettier tool online can clean it up enough to be readable).
Related
I have a very simple setup to understand the webpack basics.
Below is my project structure
While running the project and upon clicking on the buttons in the index.html page, the handlers are not getting executed instead log errors in the console.
Please find the project here
This may be a very silly question, but I could not understand this behavior. Hope someone can help me with this. Thanks!
You can't use the functions unless you export them when you use webpack.
index.js
export function click_blue() { ... }
export function click_red() { ... }
webpack.config.js
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
library: 'lib', // add this!
},
mode: 'development'
};
index.html
...
<button onclick="lib.click_red()">Red</button>
...
Check webpack output.library for more information.
I'm using gatsby-plugin-alias-imports to be able to do absolute imports like so: import { colors } from "#styles/theme"; This is set up in the gatsby-config. Now I've just added storybook to my project. Since storybook doesn't run through gatsby, the alias imports won't resolve and I get an error:
ERROR in ./src/components/Button/index.js Module not found: Error:
Can't resolve '#styles/theme' in ...
This makes sense. Storybook doesn't know what to do with #styles... - but how can I fix this?
You need to configure Storybook's Webpack to follow the same directive by adding ./src to the resolutions array. In your .storybook/webpack.config.js file, add this to the body of the function being exported (assuming you're destructuring config from the first argument):
config.resolve.modules = [
path.resolve(__dirname, "..", "src"),
"node_modules",
]
Your webpack.config.js file should look something like this when you're done:
const path = require("path")
module.exports = ({ config }) => {
// a bunch of other rules here
config.resolve.modules = [
path.resolve(__dirname, "..", "src"),
"node_modules",
]
// Alternately, for an alias:
config.resolve.alias = {
"#styles": path.resolve(__dirname, "..", "src", "styles")
}
return config
}
You need to tell the webpack config for storybook to resolve the path aliases you have set in your tsconfig.json file.
Inside your .storybook/main.js file, you need to add the following.
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin')
module.exports = {
"webpackFinal": async config => {
config.resolve.plugins.push(new TsconfigPathsPlugin())
return config
}
}
This adds the tsconfig-paths-webpack-plugin package to the storybook webpack config's resolve plugins and uses your tsconfig.json to resolve the path aliases.
This is also the exact way it would be done inside any webpack config file. I have dealt a lot with making path aliases work and this is the absolute easiest way to do it and will work every time.
In case you use #storybook/vite-builder. This neat config works for me
const tsconfigPaths = require("vite-tsconfig-paths");
...
module.exports = {
...
framework: "#storybook/react",
core: {
"builder": "#storybook/builder-vite"
},
async viteFinal(config) {
config.plugins.push(tsconfigPaths.default());
return config;
},
};
It seems that you need to create custom babel config for storybook. Include there your configurations of gatsby-plugin-alias-imports
https://storybook.js.org/docs/configurations/custom-babel-config/
There is a great possibility that you will find your solution here.
Resolve alias in webpack config: https://github.com/storybookjs/storybook/issues/3339
I am developping a library that needs to work in both node and a react app. I use a webpack 4 project that generates a UMD module, but I have a problem when I try to import it in a simple webpack project.
When I use import lib from 'myLib'; lib is undefined
This is what my lib look like
export const printMsg = function() {
return "This is a message from the lib";
};
With this webpack configuration
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "mylib.js",
library: "mylib",
libraryTarget: "umd",
umdNamedDefine: true,
globalObject: `(typeof self !== 'undefined' ? self : this)`
}
};
for now I'm using a boilerplate project (https://github.com/wbkd/webpack-starter) to test.
I used npm install --save mylib to add it, and my dist code is inside my node_modules folder.
My index.js file look like this :
import "../styles/index.scss";
import lib from "watson-tile-lib";
console.log(lib);
When I run the page I got undefined in my browser console.
Any idea ?
what is your main field in package.json? It should be the builded target like:
main: "dist/mylib.js"
I'm working on a npm package called foobar, locally, to allow me to make changes or modifications in real time without having to publish/unpublish to improve development time and sanity.
In projectTest, I have linked foobar by using the command npm link foobar. If you don't know, the npm link flag creates a symlink to your globals (you can read more about it here: https://docs.npmjs.com/cli/link)
The projectTest happens to be a Reactjs project, written in ES2015, Webpack, babel, etc; and where I do import { x } from 'package', without any issues, etc.
As mentioned, the package foobar exists in the node_modules has a link to its development directory, but for some reason, when I try to import:
import { myFn } from 'foobar'
The following error is thrown into the console:
/foobar/lib/index.js:3
export const loadImage = () => {
^^^^^^
SyntaxError: Unexpected token export
at Object.exports.runInThisContext (vm.js:78:16)
at Module._compile (module.js:543:28)
This is not expected, based in the fact that other imports inplace work perfectly; Why doesn't this happen in the other existing imports where the code is also ES2015? It's not transpiled ahead or to a static file, but in real time AFAIK, since I have webpack setup with babel loader like:
var path = require('path')
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var AssetsPlugin = require('assets-webpack-plugin')
var assetsPluginInstance = new AssetsPlugin()
module.exports = {
devtool: 'inline-source-map',
context: path.resolve(__dirname, 'src'),
entry: [
'react-hot-loader/patch',
'webpack/hot/dev-server',
'webpack-hot-middleware/client',
'babel-polyfill',
'./js/index.js'
],
output: {
path: __dirname,
publicPath: '/assets/',
filename: 'js/bundle.js?[hash]'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
'babel-loader'
]
}
...
}
I'd like to understand the reason of this happening! So, to help me trace the issue, tried an import that is not to the node_module's linked package, but instead, to the full or relative path, for example:
import { myFn } from '/bar/zoo/lar/deep/foobar'
Where I have placed an equivalent syntax/file, of a working import that is my utils or helper functions, that I use across the project without problems. The syntax is:
export const myFn = () => {
return 'myFn call!'
}
Where I import it from my app.js let's say, like:
import { myFn } from './utils' // works fine! BUT if I DO:
import { myFn } from '/path/to/packageFoobar' // I get the syntax error!
SO user #felixKling left a nice comment about webpack node_module being ignored, which I've now tested but I still get the error after removing the node_module:
(function (exports, require, module, __filename, __dirname) { export const styleObjectParser = str => {
^^^^^^
SyntaxError: Unexpected token export
at Object.exports.runInThisContext (vm.js:78:16)
at Module._compile (module.js:543:28)
From what I can see this far, is that, in the webpack dev configuration file, only the code under the context is transpiled in run time. But I might be wrong:
module.exports = {
devtool: 'inline-source-map',
context: path.resolve(__dirname, 'src'),
entry: [
'react-hot-loader/patch',
'webpack/hot/dev-server',
'webpack-hot-middleware/client',
'babel-polyfill',
'./js/index.js'
],
I'd like to confirm that changing the syntax works perfectly fine, so this is related with the context the babel-loader runs. Even though I don't understand why the syntax error happens, even when the node_module exclusion is removed.
module.exports = {
myFn: function () {
console.log('Syntax correct! myFn works!')
}
}
I am using webpack2, node v7.4.0
I think the problem is foobar project is not transpiled when linked with npm link, but projectTest shouldn't compile foobar project, it should just link it.
You have to transpile foobar with babel before you link it in other project.
You can add a build script in package.json of foobar project to transpile code into a /dist folder, and modify the main field of package.json in this way:
"main": "./dist/index.js"
Add npm run build in your development process, in order to have dist folder updated while developing foobar.
Now projectTest should link transpiled version of foobar.
I would like to build an ES6 library using Webpack.
I generate a file using a webpack.config.json like that:
module.exports = {
entry: 'src/Main.js',
output: {
path: __dirname + '/dist',
filename: 'MyLib.min.js',
libraryTarget: 'umd'
}
};
And my Main.js:
import {Car} from './Car.js';
import {House} from './House.js';
import {Character} from './Character.js';
The problem:
When I want to instantiate something in my index.html (inside <script> after including "MyLib.min.js"), I've got an error:
Uncaught ReferenceError: Character is not defined
I don't understand what is wrong with my configuration, did I miss something?
It looks like you expect Character on the global scope. You can do that inside Main.js by simply adding window.Character = Character.