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

POC build using snowpack #400

Open
rorticus opened this issue May 27, 2020 · 3 comments
Open

POC build using snowpack #400

rorticus opened this issue May 27, 2020 · 3 comments
Assignees

Comments

@rorticus
Copy link
Contributor

Investigate if its possible to build a dojo app using snowpack.

@rorticus rorticus self-assigned this May 27, 2020
@rorticus
Copy link
Contributor Author

Overall, I don't think this will go as planned as the snowpack package only exports a single function, cli, that allows you to run CLI commands. This means that we can't just pass in config or monitor the progress in any way.

Ignoring that, I tried a few different things to get a snowpack build going. Maybe someone else will have better luck.

Note that for this POC i was using a default dojo app from dojo create app --tsx

Using the defaults

snowpack seems to have sensible defaults, and I saw people using it with no configuration with good results. In this case, I couldn't get pass the install stage. It seems like it's not resolving modules properly.

⠼ snowpack installing... @dojo/framework/core/Registry, @dojo/framework/core/Registry.js, @dojo/framework/core/middleware/theme, @dojo/framework/core/middleware/theme.js, @dojo/framework/core/vdom, @dojo/framework/core/vdom.js, @dojo/framework/routing/ActiveLink, @dojo/framework/routing/ActiveLink.js, @dojo/framework/routing/Outlet, @dojo/framework/routing/Outlet.js, @dojo/framework/routing/RouterInjector, @dojo/framework/routing/RouterInjector.js, @dojo/framework/testing/renderer, @dojo/widgets/header, @dojo/widgets/header.js
✖ Cannot find module '@dojo/widgets/header.js'

I tried a couple of different options with @rollup/plugin-node-resolve and @rollup/plugin-commonjs but couldn't get anything interesting to happen.

snowpack.config.js

module.exports = {
    "installOptions": {
        "rollup": {
            "plugins": [
                require('@rollup/plugin-node-resolve').default(),
                require('@rollup/plugin-commonjs')()
            ]
        }
    }
};

Using app-scripts-react

This is the package that's installed when using create-snowpack-app and using the react typescript template. Since they are basically the same, I figured a few modifications to the configuration files in app-scripts-react might give us something close.

I ran into a couple of issues.

  • I can't get snowpack (rollup?) to recognize the .mjs versions of the dojo packages, so it imports the umd version and gets confused. I tried compiling @dojo/framework as commonjs and using that, but that got the default exports confused. i.e., the code was referencing global.default when the actual default variable was just in global.

I should also note that if you remove the .js files and keep the .mjs files in @dojo/framework, you'll get an error about not being able to find the packages.

  • When using snowpack dev, it doesn't seem to understand the TSX. It seems like its preserving JSX and confusing things downstream as it sends it right to the browser.

  • When using snowpack build, everything actually builds and js/css files are emitted to the build directory. Things don't run though due to previously mentioned commonjs/import problems with @dojo/framework.

Using a custom typescript plugin

By default, snowpack runs TypeScript code through babel, using @babel/preset-typescript for transformation. Unfortunately, since this doesn't actually use typescript, options in tsconfig are not honored. I tried writing a custom plugin to process TypeScript files.

ts.js

const ts = require('typescript');
const tsconfig = require('./tsconfig.json');

module.exports = function createPlugin(snowpackConfig, pluginOptions) {
    return {
        "defaultBuildScript": "build:mjs,js,jsx,ts,tsx",
            async build({ contents, filePath, fileContents }) {
                if(!filePath.endsWith('.ts') && !filePath.endsWith('.tsx')) {
                    return;
                }

                const result = ts.transpileModule(contents || fileContents , { compilerOptions: tsconfig.compilerOptions });

                return { result: result.outputText };
            }
    };
};

This runs tsx/ts files through Typescript before they get to snowpack, using the tsconfig from the package root. This resulted in properly generated javascript files using snowpack build by just including the plugin in the snowpack config.

snowpack.config.json

{
    "plugins": [
        "./ts"
    ]
}

This caused similar problems with commonjs and not using mjs files as the app-scripts-react option. If we could fix that, this option might be nice as it uses TypeScript to create the result and therefore the built files look more like they do with the current cli-build-app.

@maier49
Copy link
Contributor

maier49 commented Jun 10, 2020

So the mjs resolution issue was in the snowpack code itself, where they are resolving imports before passing them as input options to rollup. The rollup code itself resolves mjs modules fine but these are passed in explicitly pointing to js files. I worked around this using the installOptions.alias config in snowpack.config.json

{
    "scripts": {
        "mount:public": "mount public --to /",
        "mount:src": "mount src --to /_dist_"
    },
    "plugins": [
        "./ts"
    ],
    "installOptions": {
	    "alias": {
		    "@dojo/framework/core/Registry": "@dojo/framework/core/Registry.mjs",
		    "@dojo/framework/core/middleware/theme": "@dojo/framework/core/middleware/theme.mjs",
		    "@dojo/framework/core/vdom": "@dojo/framework/core/vdom.mjs",
		    "@dojo/framework/routing/ActiveLink": "@dojo/framework/routing/ActiveLink.mjs",
		    "@dojo/framework/routing/Outlet": "@dojo/framework/routing/Outlet.mjs",
		    "@dojo/framework/routing/RouterInjector": "@dojo/framework/routing/RouterInjector.mjs",
		    "@dojo/widgets/header": "@dojo/widgets/header/index.mjs"
	    }
    }
}

With this config (and and index.html file in public that points to the appropriate main.js and main.css files) the app started up successfully. However, theming is not working and no classes are being applied to nodes.

@maier49
Copy link
Contributor

maier49 commented Jul 6, 2020

So the last issues with theming were remedied by changing m.css files to .module.css and changing the typings and imports for these files to expect the CSS as the default export. This behavior does seem to be in snowpack itself and not rollup and there doesn't appear to be anyway to configure it.

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

2 participants