sveltejs / svelte-loader

Webpack loader for svelte components.
MIT License
594 stars 73 forks source link

Cannot build svelte components in production #98

Open d3chapma opened 5 years ago

d3chapma commented 5 years ago

I am trying to use svelte for building components and a legacy Backbone application.

The application is currently built using webpack. I added:

      rules: [
        {
          test: /\.svelte$/,
          exclude: /node_modules/,
          use: 'svelte-loader',
        },
      ]

to my webpack.config and everything seems to work fine in development, but when I build for production I get the following error:

ERROR in vendor-53f438ed5305e5f2fa59.js from UglifyJs
Unexpected token: operator (>) [/Users/dc/Projects/web/d3m/node_modules/svelte/internal.js:6,0][vendor-53f438ed5305e5f2fa59.js:46867,20]

ERROR in main-83daa955f5b3660f5e3c.js from UglifyJs
Unexpected token: punc (() [main-83daa955f5b3660f5e3c.js:84246,3]

Any thoughts on what might cause something like this?

Update: I am using webpack 3.8.1

0gust1 commented 5 years ago

ERROR in vendor-53f438ed5305e5f2fa59.js from UglifyJs

I bet you should check on the production settings. Maybe that the version of uglify that you are using probably doesn't support ES6.

0gust1 commented 5 years ago

Googling the kind of error messages you got, reinforce my intuition about ES6 + UglifyJS. Svelte compilation outputs ES6 code. So you should have a compatible UglifyJs version to handle it.

And if you want to have support for legacy browsers, like IE11, you should also use a tool like Babel or Buble, to convert your ES6 code to ES5.

Did you had the time to take a look ?

Rich-Harris commented 5 years ago

Yeah, UglifyJS is abandonware. Use Terser instead — not sure exactly how to set it up with webpack 3, but fairly sure it's possible

d3chapma commented 5 years ago

Thanks for the help. I have tried switching to Terser Legacy for Webpack 3 and many other configurations of UglifyJs/UglifyEs/Babel. Nothing has worked for me so far. I think I'll just end up upgrading to Webpack 4 and that will hopefully make things easier.

Kiho commented 5 years ago

@d3chapma This was working for me with svelte v2.x

"svelte-loader": "~2.12.0",
"uglifyjs-webpack-plugin": "^1.1.6",    
"webpack": "^3.10.0",
0gust1 commented 5 years ago

@Kiho : I think you may have forgot Babel (or another ES6=>ES5 transpiler).

The pipeline should go this way :

Svelte source => (compilation) => ES6 output => (Babel/Buble) => ES5 output => (Terser/Uglify) => ES5 minified bundle

If you don't care of old browsers :

Svelte source => (compilation) => ES6 output => (Terser) => ES6 minified bundle

0gust1 commented 5 years ago

As an example, in our webpack3 prowered project, we have the following config (module.rules part) :

Please note that the use part of loaders have to be read "from bottom".

         {
          test: /\.(html|svelte)$/, exclude: /node_modules\/(?!svelte)/,
          use: [
            { //babel loader after the svelte loader
              loader: 'babel-loader',
              options: {
                presets: 'babel-preset-env',
              }
            },
            { //svelte loader first
              loader: 'svelte-loader',
              options: {
                store: true,
                hydratable: true,
                preprocess: {
                  style: preprocessStyle('less')
                }}
            }
          ]
        },

        // JS : Process JS imports with babel
        {
          test: /\.js$/,
          loader: 'babel-loader',
          exclude: [/node_modules\/(?!svelte)/, /\.legacy.js$/],
          options: {
            presets: [['babel-preset-env', { modules: false }]],
          },
        },
meeroslav commented 4 years ago

I am using webpack 4.32.0 with terser-webpack-plugin and still have those issue:

{
  loader: 'svelte-loader',
  options: {
    emitCss: true,
    hotReload: config.mode !== 'production',
    preprocess: require('svelte-preprocess')({
      /* options */
      scss: {
        includePaths: [buildconfig.tmpFolder]
      },
      typescript: {
        compilerOptions: {
          module: 'es2015'
        }
      },
      postcss: true
    })
  }
}

and setup for terser

new TerserPlugin({
  parallel: true,
  sourceMap: false,
  terserOptions: {
    compress: {
      drop_console: true
    },
    ecma: 6
  }
})

This versions work: svelte: 3.4.0 svelte-loader: 2.13.3 svelte-preprocess: 2.9.0

This doesn't svelte: 3.6.7 svelte-loader: 2.13.3 svelte-preprocess: 2.9.0

So I'm not sure if it's svelte or svelte-loader issue. From svelte version 3.5.2 is this error visible.