Cannot use import statement outside a module
pjdevries opened this issue · 6 comments
Hi. Please accept my apologies beforehand, for my lack of knowledge and experience.
I'm trying to use the esbuild-plugin-copy
plugin, to copy several files to their final destinations, after esbuild
has done its thing. For that purpose I have a simple build.js
script, which I execute from my equally simple package.json
like so:
"scripts": { "build": "node --trace-warnings build.js" }
.
The build.js
script itself roughly looks like this:
import copy from 'esbuild-plugin-copy';
require('esbuild').build({
entryPoints: [
...
],
loader: {
...
},
bundle: true,
outdir: 'dist',
plugins: [
copy({
assets: {
from: ['./dist/*.js'],
to: ['../assets/js'],
},
}),
copy({
assets: {
from: ['./dist/*.css'],
to: ['../assets/css'],
},
})
]
}).catch(() => process.exit(1))
Without the import
and plugins
sections, the script runs fine and produces the desired output files. However, when including the import
and plugins
sections, I get the following error:
import copy from 'esbuild-plugin-copy';
^^^^^^
SyntaxError: Cannot use import statement outside a module
My extremely limited knowledge tells me I'm mixing CommonJS
and ES6
modules here. The problem is I don't know how to fix it. I have tried var copy = require('esbuild-plugin-copy')
, but that does not work.
How can I get the copy
function to work in my build script?
To use ES Module in .js
file, you will need to rename file with .mjs
ext, and add type: 'module'
in your package.json
, then you can execute it by node build.mjs
.
Also, by doing this, you cannot use require
any more, just change it to:
import copy from 'esbuild-plugin-copy';
import { build } from 'esbuild';
Thanx for the reply @linbudu599.
I did like you said. My package.json
now roughly looks like this:
{
"dependencies": {
...
},
"type": "module",
"scripts": {
"build": "node build.mjs"
},
"devDependencies": {
"esbuild": "^0.13.15",
"esbuild-plugin-copy": "^0.2.0"
}
}
and my build.mjs
file like this:
import { build } from 'esbuild';
import copy from 'esbuild-plugin-copy';
build({
entryPoints: [
...
],
loader: {
...
},
bundle: true,
outdir: 'dist',
plugins: [
copy({
assets: {
from: ['./dist/*.js'],
to: ['../assets/js'],
},
}),
copy({
assets: {
from: ['./dist/*.css'],
to: ['../assets/css'],
},
})
]
}).catch(() => process.exit(1))
The import error has disappeared, but I now get
copy({
^
TypeError: copy is not a function
Any clues what might still go wrong?
Use copy.default()
instead, because this package is built as CommonJS. (For applicability, as ESM can import CJS, CJS cannot import ESM)
I update the plugin to version 0.3.0
and now use copy.default()
as you suggested. No more error messages :) The files are copied, but unfortunately not into the right folder.
As you can see above, the to:
paths are relative, with the assumption that they are relative to the current
folder (i.e. the folder where package.json
resides). I expect the files to be copied to a sub folder of the parent
, but they are copied into a sub folder of the current
folder instead. Consider the following folder structure:
/some/path/3rdParty
package.json
../src
../dist
/some/path/com_dma
../js
../css
In this scenario, I assume /some/path/3rdParty
to be the current
folder. I would expect the files to be copied from /some/path/3rdParty/dist
to /some/path/com_dma/js
and /some/path/com_dma/css
. Instead they are copied to /some/path/3rdParty/com_dma/js
and /some/path/3rdParty/com_dma/css
.
So it seems the plugin copies the files relative to their original locations, as opposed to relative to the current
folder, which feels somewhat counterintuitive Is that assumption correct and if so, is it by design or is it a mistake? In any case, it would be helpful to include a pointer in the documentation.
to
path is calculated based on otudir
or outfil
from your esbuild options(and from
path based on cwd
), in your cases it's resolved from root/current/dist
, so using ../assets
as to
path indicates output to root/current/assets
. To use root/assets
as destination, just specify ../../assets
.
Also, I'll add tips in the documentation later.
Thanx for the clarification. It all seems to work fine now.
Thank you also for your time and patience and for making your software freely available to the rest of us.