-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Class constructor SvelteComponent cannot be invoked without 'new' #44
Comments
I have the same issue. Adding the following to "browserslist": [
"last 1 chrome versions"
], However, HMR throws an error (browser console):
Manually refreshing the page works fine, so we can provide the |
I’m aware of this issue and will try to look into it. If anyone has experience with Svelte compiler or just wants to try to fix this feel free to do so. Sent with GitHawk |
Is there a hack/fix that doesn't involve using browserslist? |
This problem seems to be related to parcel-bundler/parcel#1037 and the source from Or as @Mouvedia mentioned, use browserslist in order to get only ES6 code and not mix it with transpiled code. |
@madbrain seems like it's the only way. I've tried fixing it in the plugin a little while ago. |
I don't want to.
@madbrain can you fill it? |
I opened an issue on svelte (sveltejs/svelte#2788). Hope this would help. |
Well... after some comments on the issue I opened, it seems that So I spent some more hours of debugging and it seems that the problem is coming from Parcel itself: when an external JS asset is transformed to AST, the minimal amount of babel plugins is computed. But when external module contains no information (browserslist, babelrc, etc.), the target env serves as reference (https://github.com/parcel-bundler/parcel/blob/master/packages/core/parcel-bundler/src/transforms/babel/env.js#L21), which leads to no transpilation at all. Guys, this is a marathon... 😓 |
@madbrain there has actually been various discussions around libraries needing to explicitly mention their target env as otherwise bundlers have no way of knowing which entrypoint to pick/env to start from. There is unfortunately no standard to this as package.json is not really standardised at all. There have been some proposals and parcel just tries to figure it out based on all semi-standardised fields like browserslist. Not sure why they don't wanna mention it. But they should. |
Is it the desired behaviour to have no transpilation at all when the external module doesn't provide any hint ? |
@madbrain perhaps, imo this would make more sense. but it would slow down Parcel significantly as packages who don't have a browserslist or something similar will all get compiled (and most packages actually do target commonjs, which makes this prob not such a good idea). Which unfortunately is way too many packages. It would be great if tools like babel actually enforced a similar pattern to Parcel and use browserlist file or package.json instead of allowing defining target env in babel. Or at least not encourage it. This (having no idea what a package targets problem) was actually mentioned in a talk at Google I/O about how package creators could help improve bundle size and in Parcel's case also Bundler performance by using some target field https://youtu.be/-xZHWK-vHbQ?t=2294 (although I'm no fan of their suggested syntax, as it's a very short term solution...) Anyway the package.json "spec" still has a long way to go before it can actually help improve bundle size and bundler speed. Luckily a lot of people are trying to push these things to become standard including the Parcel team. (unfortunately also leading to multiple specs) |
A link to my original PR on this with a bunch of comments why this isn't a good idea and possible solutions: parcel-bundler/parcel#2073 |
@DeMoorJasper Bower has |
I using this temprorary workaround (thx @icopp for comment) for solve the bug. It just trigger a transpilation
{
"scripts": {
"postinstall": "cpy --rename=.browserslistrc .browserslistrc.packages node_modules/svelte"
}
}
|
I can't work out what state this is at, does this mean IE 11 + Svelte + Parcel is right out? |
This is not a workaround. It's a hack that only works if you are not supporting certains browsers. |
I couldn't make it work. But I think it is more than just this plugin, or svelte, or anything. Needless to say, without a better choice, we are moving back to writing code like it is 1999. |
This is not an issue specific to this plugin, this is an issue that is caused due to some design decisions made in Parcel. Specifically(as mentioned above) the decision not to transpile packages in the I'm subscribed to that issue, and to other issues regarding HMR, and will update this plugin when possible. Until then there is nothing we can do... |
I really wish there was an option to transpile node_modules. Can Parcel read read node_modules only once and utilize the cache to check if anything has changed? I don't like the idea of assuming all node_modules are already "standard js". |
Maybe this has been mentioned before, but babel and typescript both have options to allow transpiling of certain node_modules. If parcel would respect what the app has defined in their babel or typescript config files, then apps would have a better workaround. example within a tsconfig.json file:
|
I used parcel and svelte for several months, // postinstall.js
const fs = require('fs')
const nodeVersion = 'node 10.11'
// Patch to node_modules/*
const patch = (staticPath) => {
let folderNames = fs.readdirSync(staticPath)
for(let folderName of folderNames){
let stats = fs.statSync(staticPath + '/' + folderName)
if(! stats.isDirectory()) continue
try{
let packageFilePath = `${staticPath}/${folderName}/package.json`
let browserListFilePath = `${staticPath}/${folderName}/.browserslistrc`
let packageFileData = JSON.parse(fs.readFileSync(packageFilePath))
delete packageFileData['browserslist']
fs.writeFileSync(browserListFilePath, nodeVersion)
fs.writeFileSync(packageFilePath, JSON.stringify(packageFileData, null, 2))
// console.log(`Fixed browserlist in ${packageFilePath}`)
// Patch to node_modules/*/node_modules/*
let nestedModulePath = `${staticPath}/${folderName}/node_modules`
if(fs.existsSync(nestedModulePath)) patch(nestedModulePath)
}catch(e) {}
}
}
patch('./node_modules')
console.log(`All browserlist has been updated.`) Enter the above code into the project main folder to 'postinstall.js' {
"scripts": {
"postinstall": "rm -rf ./.cache && node ./postinstall.ts"
}
} Now, if you do CAUTIONPostinstall does not appear to run automatically on manual module installation commands such as |
If you don't want to use the browserslist solution, I wrote a Parcel plugin that forces a Babel transform on certain JS assets:
const fs = require('@parcel/fs');
const babel = require('@babel/core');
const JSAsset = require('parcel-bundler/src/assets/JSAsset');
// Only run Babel on Svelte source files
const babelConfig = {
include: ['node_modules/svelte'],
plugins: ['@babel/plugin-transform-classes']
};
module.exports = class ForceBabel extends JSAsset {
constructor(...args) {
super(...args);
}
// This overloads the JSAsset's`load` function.
// It transforms the JS file immediately after reading it,
// before Parcel has done anything.
async load() {
const code = await fs.readFile(this.name, this.encoding);
const transformed = babel.transformSync(code, {
filename: this.name,
...babelConfig
}).code;
return transformed;
}
};
const Bundler = require('parcel-bundler');
const bundler = new Bundler(`src/js/main.js`);
// This is how you add a plugin to Parcel
const path = require.resolve('./ForceBabel.js');
bundler.addAssetType('js', path);
bundler.addAssetType('mjs', path);
bundler.bundle(); If you want to use the Parcel CLI instead of the Node API, you can put |
@plmrry could you create a GitHub repository with a README for this plugin? |
This might be caused by the way babel transforms the svelte output. For example one of my components outputs this text in the class definition. class StyleGuide extends SvelteComponentDev {
constructor(options) {
super(options);
init(this, options, instance, create_fragment, safe_not_equal, {});
dispatch_dev("SvelteRegisterComponent", {
component: this,
tagName: "StyleGuide",
options,
id: create_fragment.name
});
}
} Babel and webpack turn it into this gobbledegook where this function var StyleGuide = /*#__PURE__*/function (_SvelteComponentDev) {
_inherits(StyleGuide, _SvelteComponentDev);
function StyleGuide(options) {
var _this;
_classCallCheck(this, StyleGuide);
_this = _possibleConstructorReturn(this, _getPrototypeOf(StyleGuide).call(this, options));
(0,svelte_internal__WEBPACK_IMPORTED_MODULE_15__.init)(_assertThisInitialized(_this), options, instance, create_fragment, svelte_internal__WEBPACK_IMPORTED_MODULE_15__.safe_not_equal, {});
(0,svelte_internal__WEBPACK_IMPORTED_MODULE_15__.dispatch_dev)("SvelteRegisterComponent", {
component: _assertThisInitialized(_this),
tagName: "StyleGuide",
options: options,
id: create_fragment.name
});
return _this;
} So, I made a babel config containing some customizations for const babelrc = {
presets: [
[
"@babel/preset-env",
{
corejs: 3,
targets: {
browsers: ["defaults"]
},
useBuiltIns: "usage",
/*
Svelte breaks if this tries to transform the classes. It calls these babel
methods and then throws.
+ _classCallCheck
+ _getPrototypeOf
*/
exclude: ["transform-classes"]
}
]
]
};
module.exports = babelrc; It needs a little more investigation to find out if the svelte output or the babel transform are to blame. Based on my work here I don't think it's an error with Was this helpful? Do we need to talk to anyone from the svelte team or do you think it's just babel junk? @edm00se I thought you might need this for your template. Related links: |
What's the status of this issue ? |
@Mouvedia May be you can try this, https://github.com/hmmhmmhm/svelte-template |
That may help someone else, thanks. |
@Mouvedia I have a starter that might suit your needs. No ts, but modern js transpilation, parcel, svelt 3, sass support in both global import and svelte components. It also has jest for testing. |
Was it finally fixed by parcel-bundler/parcel#7399? |
🐛 Bug Report
Hi, got some strange error with a basic "Hello world" app.
Class constructor SvelteComponent cannot be invoked without 'new'
, pointing my app.js🎛 Configuration (.svelterc, package.json, cli command)
Nothing special.
💻 Code Sample
Everything's in the repo, but the code is quite simple :
and the app.svelte is:
🌍 Your Environment
Svelte version
^3.1.0
, Parcel version^1.12.3
, plugin version3.0.0
Thanks in advance!
The text was updated successfully, but these errors were encountered: