Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fable-splitter only uses last file in project #1165

Closed
nojaf opened this issue Sep 26, 2017 · 16 comments
Closed

fable-splitter only uses last file in project #1165

nojaf opened this issue Sep 26, 2017 · 16 comments

Comments

@nojaf
Copy link
Member

nojaf commented Sep 26, 2017

Description

I'm trying to create multiple js files from a fsproj using fable-splitter.
My fsproj:

Repro code

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="App.fs" />    
    <Compile Include="Helper.fs" />
  </ItemGroup>
  <Import Project="..\.paket\Paket.Restore.targets" />
</Project>

App.fs

module FableSplit

open Fable.Core
open Fable.Core.JsInterop
open Fable.Import

let init() =
    let canvas = Browser.document.getElementsByTagName_canvas().[0]
    canvas.width <- 1000.
    canvas.height <- 800.
    let ctx = canvas.getContext_2d()
    // The (!^) operator checks and casts a value to an Erased Union type
    // See http://fable.io/docs/interacting.html#Erase-attribute
    ctx.fillStyle <- !^"rgb(200,0,0)"
    ctx.fillRect (10., 10., 55., 50.)
    ctx.fillStyle <- !^"rgba(0, 0, 200, 0.5)"
    ctx.fillRect (30., 30., 55., 50.)

init()

Helper.fs

module Helper

open Fable.Import.Browser

let private toList (nodeList:NodeListOf<Element>) =
    let length = nodeList.length - 1.0
    [0.0 .. length]
    |> List.map (fun i -> nodeList.item i  :?> HTMLElement)

let dollar selector (element:HTMLElement) =
    element.querySelectorAll selector
    |> toList

splitter.config.js

const path = require("path");
const fableUtils = require("fable-utils");

function resolve(relativePath) {
    return path.join(__dirname, relativePath);
}

module.exports = {
  entry: resolve("src/FableSplit.fsproj"),
  outDir: resolve("splitted"),
  babel: fableUtils.resolveBabelOptions({
    presets: [["es2015", { modules: false }]],
    sourceMaps: true,
  }),
  fable: {
    define: ["DEBUG"]
  }
}

Expected and actual results

Expected

Two files (App.js and Helper.js) inside the splitted folder.

Actual

Only the last item in the fsproj is being compiled.

Related information

  • Fable version (dotnet fable --version): 1.2.3
  • Operating system: Windows 7
@alfonsogarciacaro
Copy link
Member

In general Fable clients (Webpack loader, Rollup plugin, fable-splitter) start compiling the last file in the project and only request other files if they're being referenced. This is consistent with how JS projects work where there's an entry file that acts as the public interface for the project/package.

However, I also want to add the option to fable-splitter to compile all files in the project (or at least all in the base directory) for special cases (like tests projects). Until this is ready there's a little hack to make sure all projects will get compiled which is using an empty import (actually named importSideEffects). Please see how it's done in Fable unit tests.

@alfonsogarciacaro
Copy link
Member

I've published fable-splitter 0.1.19 which accepts the following config to force compilation of all project files even if they're not referenced, could you please give it a try? (You also need to upload Fable to 1.2.4)

module.exports = {
  ...
  fable: {
    ...
    extra: { allFiles: true }
  }
};

@nojaf
Copy link
Member Author

nojaf commented Sep 28, 2017

Thanks Alfonso, it worked!

I did kinda wish paket update also did the dotnet restore of my project. A bit confusing as I updated all dependencies and it was still loading stuff from 1.2.3. Only after the dotnet restore I got the multiple files.

As a last remark for anyone trying to do the same the extra configuration is not underneath fable.
For ex.

const path = require("path");
const fableUtils = require("fable-utils");

function resolve(relativePath) {
    return path.join(__dirname, relativePath);
}

module.exports = {
  entry: resolve("src/FableSplit.fsproj"),
  outDir: resolve("splitted"),
  babel: fableUtils.resolveBabelOptions({
    presets: [["es2015", { modules: false }]],
    sourceMaps: true,
  }),
  fable: {
    define: ["DEBUG"]
  },
  extra: { allFiles: true }
}

@alfonsogarciacaro
Copy link
Member

Ups, thanks for pointing that out @nojaf! Actually that's my mistake I think it should go into fable because extra can also be used to pass some values to Fable daemon. I'll fix that!

@alfonsogarciacaro
Copy link
Member

Sorry for so many changes but I realized allFiles is an exclusive option of fable-splitter so I moved it to the options root as other splitter-only options like entry or outDir. Now with fable-splitter 0.1.20 you do:

module.exports = {
  entry: ...,
  outDir: ...,
  babel: ...,
  fable: ...,
  allFiles: true
}

@nojaf
Copy link
Member Author

nojaf commented Sep 29, 2017

Tested the 0.1.20, works. Thanks!

@TheAngryByrd
Copy link

I was attempting to do the same as this issue but i'm only getting one file out.

my splitter config

const path = require("path");
const fableUtils = require("fable-utils");

function resolve(relativePath) {
    return path.join(__dirname, relativePath);
}

module.exports = {
    entry: resolve("src/FableTestSplitter.fsproj"),
    outDir: resolve("out"),
    fable: {
        define: ["DEBUG"]
    },
    babel: fableUtils.resolveBabelOptions({
        presets: [
            ["es2015", {
                modules: false
            }]
        ],
        sourceMaps: true,
    }),
    allFiles: true
}
$ dotnet fable --version
1.3.2
$ dotnet --info
.NET Command Line Tools (2.1.3)

Product Information:
 Version:            2.1.3
 Commit SHA-1 hash:  a0ca411ca5

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  10.12
 OS Platform: Darwin
 RID:         osx.10.12-x64
 Base Path:   /usr/local/share/dotnet/sdk/2.1.3/

Microsoft .NET Core Shared Framework Host

  Version  : 2.0.4
  Build    : 7f262f453d8c8479b9af91d34c013b3aa05bc1ff
$ yarn --version
1.3.2

Am I overlooking something obvious?

@Zaid-Ajaj
Copy link
Member

@TheAngryByrd Latest Fable is 1.3.7 AFAIK but you seem to have 1.3.2 maybe update to latest?

@TheAngryByrd
Copy link

@Zaid-Ajaj just did a paket update cleared bin and obj and then dotnet restore and still same results

@alfonsogarciacaro
Copy link
Member

You're right, it's not working 😕 Latest Fable is not returning the list of files for the .fsproj. I must have broken something, sorry! 😅 I'll check...

@alfonsogarciacaro
Copy link
Member

Hmm, apparently I removed that to fix #1241. Let's see if we can find a solution that solves both problems...

@alfonsogarciacaro
Copy link
Member

This should be fixed now, please update Fable to 1.3.8 and fable-splitter to 0.1.21 and tell me if you have any problem 👍

@nojaf
Copy link
Member Author

nojaf commented Jan 23, 2018

I've tested this and it worked. I do think that the Fable.Elmish.React and Fable.PowerPack are not yet compatible with the latest Fable.

@alfonsogarciacaro
Copy link
Member

@nojaf Thanks for checking! I think Fable.Elmish.React stable has to update the dependency to Fable.React 2. What problem do you have for Fable.PowerPack?

@TheAngryByrd
Copy link

Awesome!

@alfonsogarciacaro

Powerpack error I'm getting from the same project above (without using a Main.fs file)

/Users/username/.nuget/packages/fable.powerpack/1.3.2/fable/src/IndexedDB.fs(71,37): (71,41) error FSHARP: The type '(Browser.Event -> 'a)' does not have 'null' as a proper value
fable: Compilation failed at 9:18:42 AM (22.265 s)

@alfonsogarciacaro
Copy link
Member

Ah, ok. Nobody uses that module so the error only surfaces if you use the allFiles option 😉 I released Fable.PowerPack 1.3.3, should fix that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants