Reputation: 2172
Trying to set Svelte up in a new (Phoenix) project. After following this blog post I get the infamous "import and export" error. Could anyone of the Webpack/Svelte experts community have a look at the config files and suggest what might be the cause?
Webback config:
const path = require('path');
const glob = require('glob');
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = (env, options) => {
const devMode = options.mode !== 'production';
return {
optimization: {
minimizer: [
new TerserPlugin({cache: true, parallel: true, sourceMap: devMode}),
new OptimizeCSSAssetsPlugin({})
]
},
entry: {
'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js'])
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, '../priv/static/js'),
publicPath: '/js/'
},
devtool: devMode ? 'eval-cheap-module-source-map' : undefined,
resolve: {
alias: {
svelte: path.resolve('node_modules', 'svelte')
},
extensions: ['.mjs', '.js', '.svelte'],
mainFields: ['svelte', 'browser', 'module', 'main'],
modules: ['node_modules']
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.mjs$/,
include: /node_modules/,
type: "javascript/auto",
},
{
test: /\.[s]?css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader',
],
},
{
test: /\.(html|svelte)$/,
use: {
loader: 'svelte-loader',
options: {
emitCss: true,
hotReload: true
}
}
},
]
},
plugins: [
new MiniCssExtractPlugin({filename: '../css/app.css'}),
new CopyWebpackPlugin([{from: 'static/', to: '../'}])
]
.concat(devMode ? [new HardSourceWebpackPlugin()] : [])
}
};
and the resulting error:
Uncaught Error: Module parse failed: 'import' and 'export' may only appear at the top level (40:333)
File was processed with these loaders:
* ./node_modules/svelte-loader/index.js
You may need an additional loader to handle the result of these loaders.
| }
| }
> import * as ___SVELTE_HMR_HOT_API from 'project_root_path/assets/node_modules/svelte-loader/lib/hot-api.js';import ___SVELTE_HMR_HOT_API_PROXY_ADAPTER from '<project_root_path>/assets/node_modules/svelte-hmr/runtime/proxy-adapter-dom.js';if (module && module.hot) { if (false) import.meta.hot.accept(); Hello = ___SVELTE_HMR_HOT_API.applyHmr({ m: module, id: "\"js/svelte/hello.svelte\"", hotOptions: {"preserveLocalState":false,"noPreserveStateKey":["@hmr:reset","@!hmr"],"preserveAllLocalStateKey":"@hmr:keep-all","preserveLocalStateKey":"@hmr:keep","noReload":false,"optimistic":true,"acceptNamedExports":true,"acceptAccessors":true,"injectCss":true,"cssEjectDelay":100,"native":false,"compatVite":false,"importAdapterName":"___SVELTE_HMR_HOT_API_PROXY_ADAPTER","absoluteImports":true,"noOverlay":false}, Component: Hello, ProxyAdapter: ___SVELTE_HMR_HOT_API_PROXY_ADAPTER, acceptable: true, cssId: undefined, nonCssHash: undefined, ignoreCss: true, }); }
| export default Hello;
|
at eval (hello.svelte:1)
at Object../js/svelte/hello.svelte (app.js:164)
at __webpack_require__ (app.js:20)
at webpackContext (eval at ./js/svelte sync recursive ^\.\/.*\.svelte$ (app.js:142), <anonymous>:8:9)
at eval (svelte.js?3a38:51)
at Array.forEach (<anonymous>)
at window.onload (svelte.js?3a38:41)
eval @ hello.svelte:1
./js/svelte/hello.svelte @ app.js:164
__webpack_require__ @ app.js:20
webpackContext @ .*\.svelte$?acdf:8
eval @ svelte.js?3a38:51
window.onload @ svelte.js?3a38:41
load (async)
eval @ svelte.js?3a38:40
./js/svelte.js @ app.js:153
__webpack_require__ @ app.js:20
eval @ app.js?7473:1
./js/app.js @ app.js:120
__webpack_require__ @ app.js:20
0 @ app.js:175
__webpack_require__ @ app.js:20
(anonymous) @ app.js:84
(anonymous) @ app.js:87
Two other involved files:
svelte.js
:
const context = require.context("./svelte", false, /\.svelte/);
window.onload = function() {
context.keys().forEach((file) => {
const componentName = file.replace(/\.\/|\.svelte/g, '');
const targetId = `svelte-${componentName}-root`;
const root = document.getElementById(targetId);
if(!root){
return;
}
const requiredApp = require(`./svelte/${componentName}.svelte`);
const props = root.getAttribute('data-props');
let parsedProps = {};
if(props){
parsedProps = JSON.parse(props);
}
new requiredApp.default({
target: root,
props: parsedProps
});
});
};
and the trivial hello.svelte
one:
<script>
let name = 'Svelte';
</script>
<h1>Hello from {name}!</h1>
Upvotes: 0
Views: 1220