首页 > 解决方案 > Svelte - “'import' 和 'export' 可能只出现在顶层”错误

问题描述

试图在一个新的(凤凰)项目中设置 Svelte。在关注这篇博文之后,我得到了臭名昭著的“导入和导出”错误。Webpack/Svelte 专家社区的任何人都可以查看配置文件并提出可能的原因吗?

网页配置:

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()] : [])
    }
};

以及由此产生的错误:

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

另外两个涉及的文件 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
        });
    });
};

和微不足道的hello.svelte一个:

<script>
    let name = 'Svelte';
</script>

<h1>Hello from {name}!</h1>

标签: javascriptnode.jswebpacksvelte-3

解决方案


'svelte-loader'差异中列出的降级"^3.1.1"到解决了这个问题。它是由这个问题引起的。^2.13.6"


推荐阅读