You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
With Rails 7, when migrating away from webpacker and trying to move most of the javascript to importmaps, I came with a configuration that integrates nicely webpack and importmaps:
Use raw ES6 modules for application code
Use webpack for (legacy application code and) NPM dependencies by configuring webpack to generate ES6 modules
This is especially nice when you want to avoid fetching dependencies from the Internet and want to serve all the assets from the rails server. You can also use NPM tooling to track dependencies and audit them more easily. Also, some dependencies have a gazillion files and not all are working as raw ES6 modules and requires some bundling. See #153
I configured my webpack with:
ES6 support (experiments.outputModule and optimization.moduleIds = deterministic)
generating ES6 modules (output.library.type = module and output.environment.module = true)
loading external modules as ES6 modules (externalsType = module)
bundle splitting via ES6 modules (output.chunkLoading = import and output.chunkFormat = module with optimization.runtimeChunk = single)
generating files without a content hash in public/assets. I'm not putting them in app/assets/build to be fed to the rails asset pipeline because this breaks the importmaps
Then I configured config/importmap.rb to use paths from the webpack generated assets:
This way, bootstrap and jquery are available as ES6 modules declared in import maps.
It would be great if such integration was easier, in particular if there was a way to automatically handle webpack files with a content hash.
webpack.config.js:
constpath=require('path')constwebpack=require('webpack')constmode=(process.env.NODE_ENV==='development') ? 'development' : 'production'constproduction=(process.env.RAILS_ENV==='production')constMiniCssExtractPlugin=require('mini-css-extract-plugin')constRemoveEmptyScriptsPlugin=require('webpack-remove-empty-scripts')constBundleAnalyzerPlugin=require('webpack-bundle-analyzer').BundleAnalyzerPluginmodule.exports={
mode,experiments: {outputModule: true,},devtool: production ? 'source-map' : 'eval-source-map',// Declare the modules imported from outside// there you can declare the modules available in the importmap// you want to import as ES6 from within webpack externalsType: 'module',externals: {'@hotwired/stimulus': '@hotwired/stimulus','controllers/application': 'controllers/application','lib/loader': 'lib/loader',},entry: {// application code bundled with webpackwebpack: {dependOn: ['jquery','bootstrap'],import: ['./app/webpack/webpack.js'],},// NPM dependencies available to webpack AND importmap as ES6 modulesbootstrap: {dependOn: ['jquery'],import: 'bootstrap/dist/js/bootstrap.bundle.js',},jquery: './app/webpack/jquery.js',},// Where to put the generated files, and how to generate them (ES6 module)output: {filename: '[name].js',path: path.resolve(__dirname,'public/assets/'),library: {type: 'module',},environment: {module: true,},chunkLoading: 'import',chunkFormat: 'module',sourceMapFilename: '[file]-[contenthash].digested.map',},// Configurationmodule: {rules: [// Add CSS/SASS/SCSS rule with loaders{test: /\.(?:sa|sc|c)ss$/i,use: [MiniCssExtractPlugin.loader,'css-loader','sass-loader'],},// Assets{test: /\.(png|jpe?g|gif|eot|woff2|woff|ttf|svg|ico)$/i,type: 'asset/resource',},],},resolve: {// Add additional file typesextensions: ['.js','.jsx','.scss','.css'],modules: [path.resolve(__dirname,'app/assets'),'node_modules']},optimization: {moduleIds: 'deterministic',runtimeChunk: 'single',// multiple entry points with code splitingminimize: !production,},watchOptions: {ignored: ['**/node_modules'],},devServer: {headers: {'Access-Control-Allow-Origin': '*','Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS','Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization'}},plugins: [process.env.ANALYSE ? newBundleAnalyzerPlugin() : null,newRemoveEmptyScriptsPlugin(),newMiniCssExtractPlugin(),newwebpack.ProvidePlugin({$: 'jquery',jQuery: 'jquery',jquery: 'jquery',}),newwebpack.optimize.LimitChunkCountPlugin({maxChunks: 1})].filter(x=>x)}
The text was updated successfully, but these errors were encountered:
With Rails 7, when migrating away from webpacker and trying to move most of the javascript to importmaps, I came with a configuration that integrates nicely webpack and importmaps:
This is especially nice when you want to avoid fetching dependencies from the Internet and want to serve all the assets from the rails server. You can also use NPM tooling to track dependencies and audit them more easily. Also, some dependencies have a gazillion files and not all are working as raw ES6 modules and requires some bundling. See #153
I configured my webpack with:
experiments.outputModule
andoptimization.moduleIds
=deterministic
)output.library.type
=module
andoutput.environment.module
=true
)externalsType
=module
)output.chunkLoading
=import
andoutput.chunkFormat
=module
withoptimization.runtimeChunk
=single
)public/assets
. I'm not putting them inapp/assets/build
to be fed to the rails asset pipeline because this breaks the importmapsThen I configured
config/importmap.rb
to use paths from the webpack generated assets:This way, bootstrap and jquery are available as ES6 modules declared in import maps.
It would be great if such integration was easier, in particular if there was a way to automatically handle webpack files with a content hash.
webpack.config.js
:The text was updated successfully, but these errors were encountered: