slate icon indicating copy to clipboard operation
slate copied to clipboard

Integrating TypeScript, React and Relay (or any other third-party library) into the build process

Open ZoltanDalmadi opened this issue 7 years ago • 10 comments

We have tried to integrate TypeScript, React and Relay into the build process. We managed to get TypeScript working by providing a custom webpack config (both for dev and prod) in slate.config.js, using awesome-ts-loader.

Problem 1:

  • Slate is not able to collect .ts files during the build process, so we had to provide a custom script that does that (similarly how packages/slate-tools/tools/webpack/entrypoint.js does). This way it could read and compile the .ts files.
  • However, the auto-generated script-tags snippet is not able to detect script files (because they are .ts files), so the loading / preloading logic does not work, it just includes every script on all pages, which is sub-optimal and error-prone.

After digging through Slate's source code and documentation, we have found that it can pick up a .babelrc file from the project root. So our next step was to skip TypeScript and use babel-preset-react to compile .js files (with JSX expressions).

Problem 2:

While this worked, if we used import * as React from 'react' in any script where we wanted to use React, Slate created a separate vendor bundle for the script (e.g. product.theme.js had a [email protected]). While this is good, the problem is that for every script there will be a separate vendor bundle with React in it, and this means the browser would download the same library multiple times.

We have solved this issue by not importing React in the scripts, but assume it is available globally and use a CDN to provide it.

Then we tried to integrate Relay. The problem with it is it does not have a proper CDN build, so we have to bundle it, but the problem of separate vendor chunk creation for all scripts where it is imported is the same here.

Problem 3:

The above method is not working well with slate-tools watch, because the embedded express server serves the webpack bundled files, while it should only compile the JSX expressions. I guess it could be solved by providing a different dev config in slate.config.js? It is very cumbersome during development to slate-tools deploy and refresh the browser manually after every change.

Summary

  • Is there a way to efficiently (e.g. only once) bundle third party libraries (whose don't have a proper CDN version) with Slate (not just React or Relay)?
  • Is there a straightforward way to support TypeScript files?
  • Is there a solution to this problem that is working well with slate-tools watch?

ZoltanDalmadi avatar Jul 03 '18 09:07 ZoltanDalmadi

@ZoltanDalmadi sounds really cool what you're exploring! At this point it sounds like you know more this then we do at the moment. Afraid I can't be of much help. Keep us posted on your progress and even open a PR if you think you're onto something 😄

t-kelly avatar Jul 09 '18 15:07 t-kelly

Jumping onboard this issue instead of creating another one - I'm experimenting with Vue JS and would love some insight on how to incorporate Vue Loader into the watch / build process so I can compile .vue files.

Currently just adding it into slate.config.js via installation guide doesn't seem to have any effect:

slate.config.js:

const VueLoaderPlugin = require('vue-loader/lib/plugin');
...
  slateTools: {
    extends: {
      dev: {
        resolve: {alias},
        module: {
          rules: [
            // ... other rules
            {
              test: /\.vue$/,
              loader: 'vue-loader'
            }
          ]
        },
        plugins: [
          new VueLoaderPlugin()
        ],
...

wrainbird avatar Jul 13 '18 06:07 wrainbird

Hey @rainerbird! Just letting you know @ZoltanDalmadi works with us at Createur. Thought I'd jump in here as well.

An update from our side: We have unfortunately had to drop Slate as our build process for the time being, due to a few similar issues. We're currently rolling our own build process using Skeleton. We may come back to Slate when we have more time to troubleshoot, or contribute full solutions.

bodog avatar Jul 13 '18 06:07 bodog

Hi @bodog thanks for the update.

I'm new to Slate and webpack in general, picking a few things here and there but currently loving Slate so far from a base level.

I've been using Vue a lot of outside of Shopify and hoping to marry the two together, will keep an eye on this and see if @t-kelly can provide any pointers or insight. Otherwise will make it a personal challenge to see if I can make something work and update it here!

wrainbird avatar Jul 16 '18 00:07 wrainbird

@rainerbird super interested to hear about anything you figure out when it comes to Vue + Shopify. I've been exploring it on the side in hopes of building something like vue-loader for Liquid. The ultimate goal is to hopefully get us moving towards custom elements and truly modular theme code...

Maybe open a separate issue for Vue updates and we can keep this one focused on React?

t-kelly avatar Jul 17 '18 14:07 t-kelly

@bodog @t-kelly @rainerbird very interested in more closely integrating vue with the new slate-tools webpack

previously i've created a sub-folder with a vue-cli project and add a script to compile and migrate the compiled app into the parent theme manually.

curious the best way to try and accomplish using this vue-loader directly in the theme config

sebbean avatar Jul 27 '18 20:07 sebbean

Not sure if this is the same error that others have been running into but we (@the-working-party) have been experimenting with Vue and Slate recently and are in the process of migrating to slate 1.0 as well.

We initially ran into this issue of Vue Loader not working even though we'd added the correct information into slate.config.js.

We ran into this error:

Module build failed (from ../node_modules/vue-loader/lib/index.js):
Error: [vue-loader] vue-template-compiler must be installed as a peer dependency, or a compatible compiler implementation must be passed via options.

vue-template-compiler should have been installed as a dependency for vue-loader but it doesn't seem to have worked correctly. Our work around to this was to just install vue-template-compiler as a seperate dependency and we've been able to compile and load Vue components fine since we've done this.

allanarmstrong avatar Sep 04 '18 02:09 allanarmstrong

I stumbled across this issue this evening while tinkering with Slate's build process, and actually was able to integrate Typescript file loading without any apparent difficulty.

Some steps I took to do this:

  • npm i typescript ts-loader --save
  • Setup a base tsconfig.json file in the project root
{
    "compilerOptions": {
        "noImplicitAny": true,
        "module": "es6",
        "moduleResolution": "node",
        "allowJs": true
    },
    "include": [
        "src/scripts/**/*.ts"
    ],
    "exclude": [
        "node_modules",
        "dist/*"
    ]
}
  • Added the rules for file loading in slate.config.js
const rules = [
  {
    test: /\.ts?$/,
    use: 'ts-loader',
    exclude: /node_modules/,
  }
];
  • And then include the new rules in the Webpack extend
module.exports = {
  // ...
  'webpack.extend': {
    module: { rules },
    // ...
  },
  // ...
};

It's not :100: perfect, you'll have to use some @ts-ignore's to get around untyped packages, but that seems to be expected when integrating TS into an existing project. But as far as Slate's ability to load/compile TS assets, and report type errors, it all looks to be working. slate-ts

curiouscrusher avatar Oct 15 '19 03:10 curiouscrusher

@curiouscrusher what version of slate did you implement this on, i've had this working in much earlier versions but since i've updated to 1.0.0-beta.19 i'm getting module resolve issues.

BeardedC0der avatar Oct 23 '19 15:10 BeardedC0der

@Synergy23 Great question, I was actually on 1.0.0-beta.17 when I tried this the other week. I've since updated to 1.0.0-beta.19 and haven't tried it again. I did see a lot of changes in those last two versions though, maybe one of the new Slate plugins is interfering in the newer Beta. I'll run through the same process on Beta 19 when I get a chance and see what the outcome is.

curiouscrusher avatar Oct 23 '19 18:10 curiouscrusher