webpack-contrib/imports-loader

'import' and 'export' may only appear at the top level

yqrashawn opened this issue · 9 comments

Module parse failed: /path/to/project/node_modules/imports-loader/index.js?this=>window!/path/to/project/src/entry.js 'import' and 'export' may only appear at the top level (4:0)
You may need an appropriate loader to handle this file type.
| (function() {
|
| import './NameSpace';
| import './Polyfill';
    rules: [
      {
        test: regx,
        use: [
          {
            loader: "imports-loader?this=>window",
          },
        ],
      },
    ],

But import 'imports-loader?this=>window./NameSpace'; this works fine.

Are there any chance to get some feedback about this issue? If it's expected of it's a bug? I am experiencing the same issue @d3viant0ne

// main.js
require('imports-loader?this=>window!./myExportFile')

// myExportFile.js
const foo = { bar: 'example' }
export foo;

But if you change export to module.exports, it works fine

@yqrashawn regx should be very specific: test: require.resolve("some-module"), it should only cover the few files where this is required

@ematipico This is normal because your code is wrapped in an iife:

imports-loader/index.js

Lines 25 to 27 in abea1c2

if(name === "this") {
imports.push("(function() {");
postfixes.unshift("}.call(" + value + "));");

As per es module specs, you can only have import/export at the top level of your file (not wrapped in a function, an if condition...)

@mastilver Thank you for your feedback!

import _ from 'lodash';
import { cube } from './math';
import Print from './print'

if(process.env.NODE_ENV !== 'production') {
	console.log('development');
}
// import './style.css';
function component (  ) {
	var elm = document.createElement('div');
	var btn = document.createElement('button');
	var br = document.createElement('br');

	elm.innerHTML = join(['hel1lo','webpack'], ' ');
	// elm.innerHTML = ['hello webpac1k!'].join(' ');
	btn.innerHTML = 'click print';
	this.alert('Hmmm, this probably isn\'t a great idea...');
	elm.appendChild(br);
	elm.appendChild(btn);
	btn.onclick = Print.bind(null, 'hello')
	return elm;
}
document.body.appendChild(component())
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');

module.exports = {
	entry: {
		app: './src/index.js',
		vendor: ['lodash']
		another: './src/another-module.js'
	},
	module: {
		rules: [
			{
				test: require.resolve('./src/index.js'),
				use: 'imports-loader?this=>window'
			},
			{
				test: /\.css$/,
				use: [
					'style-loader',
					'css-loader'
				]
			},
			{
				test: /\.(png|svg|jpg|gif)$/,
				use: [
					'file-loader'
				]
			},
			{
				test: /\.(woff|woff2|eot|ttf|otf)$/,
				use:[
					'file-loader'
				]
			},
			{
				test: /\.(csv|tsv)$/,
				use: [
					'csv-loader'
				]
			},
			{
				test: /\.xml$/,
				use: [
					'xml-loader'
				]
			},

		]
	},
	plugins: [
		new CleanWebpackPlugin(['dist']),
		new HtmlWebpackPlugin({
			title: 'production'
		}),
		new webpack.optimize.CommonsChunkPlugin({
			name: 'vendor'
		}),

		new webpack.optimize.CommonsChunkPlugin({
			name: 'runtime'
		}),
		new webpack.ProvidePlugin({
			join: ['lodash', 'join']
		})

	],
	output: {
		filename: '[name].[hash].bundle.js',
		path: path.resolve(__dirname, 'dist'),
		chunkFilename: '[name].bundle.js'
	}
}

Hi, I'm a webpack beginner. I followed the webpack official guide using imports-loader and found an error

ERROR in ./src/index.js
Module parse failed: 'import' and 'export' may only appear at the top level (7:0)
You may need an appropriate loader to handle this file type.
|  * Created by Administrator on 2017/10/23.
|  */
| import _ from 'lodash';
| import { cube } from './math';
| import Print from './print'
 @ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/index.js

@SteinNs I had the same issue then I found that imports-loader just does this to my module:

/* src/index.js */
(function () {
  // my module
}.call(window));

If there is an import statement in the module, webpack will throw an error to the terminal because the statement is in a function, not at the top level. You can use CommonJS require function instead.

@michaelzhng thanks for your solution:)

Mh, what do you mean with "fixed", @evilebottnawi ?

I'm using the current version of imports-loader (1.2.0), but can confirm this issue still exists.

@chkpnt please open a new issue with reproducible test repo