cancel
Showing results for 
Search instead for 
Did you mean: 
Michaelfp

Using SASS on your PCF Project

In continuous of the last post that I wrote about using Python inside our Power Apps Component Framework.  I this post I'll show how we can user SASS inside our PCF projects.

 

If you don´t know what it is SASS. It's a preprocessor style sheet language, that increases some actions that are not supported on the CSS.  

 

Using the same approach for the python language I builder an npm package that helps to use the sass. Because the PCF using webpack to transform all the typescript code into javascript, which is supported by the browsers. For this they using an approach for the components that are called loader.

 

Loaders are plugin that pre-processes files different from javascript. Any kind of type that is different from javascript you will need a loader to pre-process before getting the code available for the browser. If you want more information about loaders you just go ahead in this link -> https://webpack.js.org/loaders/

 

Let's go for the funny things! 😎

 

Create your PCF project. Could be both Field or Dataset. After creating the project, we will install the packages.

 

 

 

 

npm install --save-dev pcf-sass-loader file-loader extract-loader css-loader postcss-loader sass-loader

 

 

 

 

God! Now we need to make some changes to the webpack build process inside our pcf. Unfortunately, Microsoft did not release a location that we can add modules, loaders, and plugins without change the pcf-scripts.

 

Open the location /node_modules/pcf-scripts and edit the file webpackconfig.js

 

2020-07-02_220655.jpg

 

Now, find the method getWebPackConfig, on the module code, inside the rules, add the following piece of code.

 

 

 

 

{
                    test: /\.scss$/, //find per files that is sass
                    use: [
                       
                        {
                            loader: require.resolve('file-loader'),
                            options: {
                                name: '[folder]/[name].css' // create the compiled file in the same location that is configured in the project
                            }
                        },
                         {
                            loader: require.resolve("pcf-sass-loader"),
                        },
                        {
                            loader: require.resolve('extract-loader')
                        }, {
                            loader: require.resolve('css-loader'),
                            options: {
                                url: true
                            }
                        }, {
                            loader: require.resolve('postcss-loader')
                        }, {
                            loader: require.resolve('sass-loader')
                        }
                       
                    ]
                },

 

 

 

 

Now, we need to change our manifest file and put the same name that is using on ".sass" file, to execute the copy on the output. At this time is not possible to change the manifest before the build and because of the framework signal that CSS file is referenced.

 

2020-07-02_221330.jpg

 

Now, it just executes the build running "npm run build" and magics begin! 😄 

 

You will see that a new CSS file (with the same name of sass file) was created in the same folder. This is required because to do the reference.

 

Comments

Hi Michael,
I read your and I followed step-by-step your procedure.
My goal is reference all the _semantic.css_ library in my PCF by Sass as suggested by Microsoft. 

Here the details, in "PCFfolder" I added:

 "index.ts" 

"SemanticControl.tsx" 

"ControlManifest.Input.xml" (with the line:  <css path="css/semanticUI.css" order="1"/>)  and a subfolder: css with a file: "semanticUI.scss" 

 

  • The "semanticUI.scss" contains the one import line:

 

#pcf-semantic-control {
@import '../../node_modules/semantic-ui-css/semantic.css';
} 

 



After npm installation of "pcf-sass-loader", I modified the /node_modules/pcf-scripts/webpackconfig.js like this:

 

exports.generateStub = generateStub;
function getWebpackConfig(control, controlOutputDir, buildMode, watchFlag) {
    const entryPoint = path.resolve(control.getControlPath(), control.getCodeRelativePath());
    let customConfig = {};
    const customConfigPath = path.resolve(control.getControlPath(), '..', constants.WEBPACK_CUSTOMIZATION_FILE_NAME);
    const featureMgr = new featureManager_1.FeatureManager();
    if (featureMgr.isFeatureEnabled('pcfAllowCustomWebpack') && fs.existsSync(customConfigPath)) {
        customConfig = require(customConfigPath);
    }
    const oobConfig = {
        // `production` mode will minify, while `development` will optimize for debugging.
        mode: buildMode,
        watch: watchFlag,
        watchOptions: {
            aggregateTimeout: 500
        },
        // Tells webpack where to start walking the graph of dependencies
        entry: entryPoint,
        output: {
            // This library value control what global variable the output control is placed in.
            library: constants.TEMP_NAMESPACE,
            pathinfo: true,
            filename: constants.BUNDLE_NAME,
            path: controlOutputDir
        },
        resolve: {
            // Tell webpack which extensions to try when it is looking for a file.
            extensions: ['.ts', '.tsx', '.js', '.jsx'],
            plugins: [new awesome_typescript_loader_1.TsConfigPathsPlugin()]
        },
        module: {
            rules: [
                {
                    // Tells webpack how to load files with TS or TSX extensions.
                    test: /\.(ts|tsx)$/,
                    use: [
                        babelLoader,
                        {
                            loader: require.resolve('ts-loader')
                        }
                    ],
                    exclude: /node_modules/
                },
                {
                    // Tell webpack how to handle JS or JSX files
                    test: /\.(js|jsx)$/,
                    use: [babelLoader]
                },
                // Here My Update based on: https://powerusers.microsoft.com/t5/News-Announcements/Using-SASS-on-your-PCF-Project/ba-p/614222
                {
                    test: /\.scss$/, //find per files that is sass
                    use: [
                        {
                            loader: require.resolve('file-loader'),
                            options: {
                                name: '[folder]/[name].css' // create the compiled file in the same location that is configured in the project
                            }
                        },
                        {
                            loader: require.resolve("pcf-sass-loader"),
                        },
                        {
                            loader: require.resolve('extract-loader')
                        }, 
                        {
                            loader: require.resolve('css-loader'),
                            options: 
                            {
                                url: true
                            }
                        }, 
                        {
                            loader: require.resolve('postcss-loader')
                        }, 
                        {
                            loader: require.resolve('sass-loader')
                        }
                    ]
                }
            ]
        }
    };
    const mergedConfig = Object.assign(Object.assign({}, customConfig), oobConfig);
    if (customConfig.output) {
        Object.assign(mergedConfig.output, customConfig.output);
    }
    return mergedConfig;
}


When i prompt npm run build from the "PCFfolder" path, for my opinion the webpack pcf-sass-loader can't find the "semanticUI.scss" and is not able to convert it to .css file.....
PCF CLI give me a red error message: 

Failed:[pcf-1011] [Error] Resource file ...\PCFfolder\css\semanticUI.css not found. 

 and I can't test my PCF Control.

So, I think... is your procedure right? Because I don't know where I'm wrong.... and on Web there aren't other solutions for Sass preprocessor in PCF.

Thanks!

 

 

 

 

 

 

Nicely done

any idea how to implement python code in power apps?

 

@David_Pezzoli Hello!

Do you have the full build log to share?

Hi, How can do the same, for loading html and js files?