rails / webpacker

Use Webpack to manage app-like JavaScript modules in Rails
MIT License
5.31k stars 1.47k forks source link

Script lazy loading #1463

Closed VladZen closed 3 years ago

VladZen commented 6 years ago

Hi!) Is there any way to make import() function working? I've tried to async load some brace configurations for ace editor and found some strange behavior: webpack is compiling right but attempt to load script ends with 404. So i can suppose, that scripts simply are not copied to scripts folder. What am i doing wrong?

Thanks webpacker's developers for all of you doing!

renchap commented 6 years ago

Can you share a simple repo reproducing the problem, or the relevant code from your app?

import() works fine for me.

VladZen commented 6 years ago

@renchap

I'm using vue2-ace-editor's basic implementation except the fact of using import() instead of require()

<editor v-model="snippet.content"
             @init="aceInit"
             lang="html"
             height="400"
             class="form-control" />

Here is aceInit function

aceInit () {
  import('brace');
  import('brace/mode/html');
  import('brace/theme/chrome');
},

It looks like:

When i'm trying to load entry point for this page, it looks fine and it loads pack from assets

It seems i've some troubles with the evenness of hands. =)

UPD: Also i see this files in packs dir, but the're named as 21 and 22

brianlaw033 commented 6 years ago

@renchap Do u mind sharing what config is needed in webpack4 so that import() will work?

here's my config:

const path = require('path')
const webpack = require('webpack')
const dotenv = require('dotenv')

const customConfig = {
  devtool: 'inline-source-map', // use 'source-map' for easier debug
  module: {
    noParse: [/moment.js/], // Excludes ALL locales
    rules: [
      {
        enforce: 'pre',
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'eslint-loader',
        options: {
          fix: true,
          emitWarning: true
        }
      },
      {
        test: /\.js$/,
        exclude: [
          // Preventing build error:
          // ERROR in ./node_modules/react-google-maps/lib/index.js
          // Module build failed: Error: Plugin 0 specified in "node_modules/react-google-maps/package.json" provided an invalid property of "__wrapped__"
          path.resolve(__dirname, '../../node_modules/react-google-maps'),
          path.resolve(__dirname, '../../node_modules/action-cable-react-jwt')
        ],
        use: {
          loader: 'babel-loader',
          options: {
            cacheDirectory: true,
            // This aliases 'react-native' to 'react-native-web' and includes only
            // the modules needed by the app
            plugins: ['react-native-web'],
            // The 'react-native' preset is recommended (or use your own .babelrc)
            presets: ['react-native']
          }
        }
      },
      {
        test: /\.svg$/,
        include: [
          path.resolve(__dirname, '../../web_app/src/fonts/icons.svg')
        ],
        loader: 'svg-sprite-loader'
      }
    ]
  }
}

const fileLoader = environment.loaders.get('file')
fileLoader.exclude = path.resolve(__dirname, '../../web_app/src/fonts/icons.svg')

environment.config.merge(customConfig)

// Dot env files
const dotenvFiles = [
  path.resolve(__dirname, `../../web_app/.env.${process.env.NODE_ENV}`),
  path.resolve(__dirname, `../../web_app/.env`)
]
dotenvFiles.forEach((dotenvFile) => {
  dotenv.config({ path: dotenvFile, silent: true })
})

environment.plugins.prepend('Environment', new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(process.env))))

const V4Config = {
  mode: 'none',
  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendor',
          chunks: 'all'
        }
      }
    },
    runtimeChunk: {
      name: 'manifest'
    }
  }
}

environment.config.merge(V4Config)

environment.plugins.append('HashedModuleIds', new webpack.HashedModuleIdsPlugin())

// Moment fix
environment.plugins.append(
  'Moment',
  new webpack.ContextReplacementPlugin(/moment[\\\/]locale$/, /^\.\/(en-gb|zh-hk|zh-cn)$/)
)

// Done
module.exports = environment
guillaumebriday commented 4 years ago

I think you could close this issue now.

You will find lazy loading documentation here and here

josemigallas commented 1 year ago

@guillaumebriday the links are broken. Is that documentation still available? I can't find it.

josemigallas commented 1 year ago

Found one of them for 5-x-stable: https://github.com/rails/webpacker/blob/5-x-stable/docs/es6.md#dynamiclazy-chunk-loading