Use my own javascript files in phoenix with webpack

I create a new project with phoenix and create a simple file test.js in assets/js/

//test.js
export const hello = hello(){
    console.log("Ola")
}

Also in default index page I put a tag <script> hello() </script> on body page. I expected that string Ola will printed in console but a error saying that this function not exists is raised.

So I put import in app.js like this: import {hello} from "test.js" , but still raising error. What I`m doing wrong?

Put that method inside app.js

Or maybe you could move this file inside vendors folder

This not works… I’m testing with browser console , when I run hello() returns Uncaught ReferenceError. But if call hello() from inside app.js then I can see "Ola" in output console.

Ok, put that file inside your static folder and then inside your_app_web.ex put your filename inside plug Plug.Static , on only: ~w(css fonts images favicon.ico robots.txt test.js) and hopefully it will work

I can access this file in /test.js but when call in console same error is raised.

This is expected. Code bundled with webpack is not available in the global namespace.

If you want to be able to call your code from the console or other included scripts you should make it available exxplicitly with window.hello = hello.

Also I think there is a webpack config option that allows to define the name of the variable that is defined in window that will reference the export default value of your main file.

2 Likes

You can build a library with webpack…

    // Library Bundle
    {
      entry: {
        test_lib: './js/test.js',
      },
      output: {
        filename: 'js/[name].js',
        path: path.resolve(__dirname, '../priv/static'),
        libraryTarget: 'var',
        library: 'EntryPoint'
      },
      module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
              loader: 'babel-loader'
            }
          },
        ]
      },
    }

Then use it as EntryPoint.hello() if You don’t forget to add test_lib to the layout.

<script defer type="text/javascript" src="<%= Routes.static_path(@conn, "/js/test_libs.js") %>">
</script>

If You still want to have the apps bundle, make webpack.config.js return an array instead of an object…

return [
  {}, # usual apps code
  {}  # library code
]
2 Likes