pnp/docker-spfx

On Premises Docker Image

lisaandsoftware opened this issue · 16 comments

I attempted to use the m365pnp/spfx:onprem docker image to spin off a container for my development environment but the build failed. Are the node and npm versions correct?

Can you share some more information about what you did exactly and what kind of error you've seen so that we can see if we can reproduce it? I appreciate your help.

Hi,

I have docker desktop installed on my client Windows 10 pro laptop

Created a new folder for the project
Opened the terminal and ran the following:
docker run -it --rm --name L3H -v ${PWD}:/usr/app/spfx -p 4321:4321 -p 35729:35729 m365pnp/spfx:onprem

Ran the generator:
Yo @microsoft/sharepoint

Ran the following:
Gulp serve

ReferenceError: primordials is not defined.

I noticed that when I inspected the docker image, #14 indicates Node.js version 14.17.0. I thought only Node.js version 8 was supported for onprem?
Also, I have the following gulp versions:
CLI version: 2.3.0
Local version: 3.9.1

I wish I had the option to work with SharePoint online, but my projects are all built for on prem. Thank you for your guidance :)

I'm not sure if that is related or not but for the onprem version you will also need port 5432

Port 5432 is open and working. I believe it is related to the version of Node.js for on prem. I was able to use Node.js version v8.17.0-x64 and compile locally. I believe the issue is with the Node.js version for the onprem image. If there is a trick to get Node.js version 14.17.0 to work with onprem, I would love know. I'm not a big fan of being stuck with old versions of software and not benefiting from the fixes. Your insight is much appreciated.

This issue has to do with the fact that SPFx v1.12.1, which is the latest version that supports creating on-prem projects, requires Node 12/14, but the on-prem project that it creates and which uses SPFx v1.4.1, requires Node 6/8. Specifically, it's about gulp@3 having a dependency that's patching Node up to v11 but not higher.

I think the best way forward for us, would be to label the v1.4.1 image as onprem so that there's no discrepancy between the set of dependencies used by the generator and the projects it scaffolds.

I'm not a big fan of being stuck with old versions of software and not benefiting from the fixes. Your insight is much appreciated.

Unfortunately, we can't do much about this, as SPFx v1.4.1 hasn't been updated since its release and uses a pretty dated set of dependencies.

Thank you for the information. :)

@shurick81 agreed that it would be acceptable to label the v1.4.1 image as onprem?

let me try to formulate the issue in a slightly different angle:

best version of docker image for scaffolding new on premise projects is v1.12.1 and it creates on premise project that have v1.4.1
best version of docker image for debugging SPFx v1.4.1 projects is our v1.4.1 image

Is that about right?

best version of docker image for scaffolding new on premise projects is v1.12.1 and it creates on premise project that have v1.4.1

Unfortunately not, because v1.12.1 requires Node@10,12,14 while v1.4.1 Node@6,8. So if you use generator v1.12.1 to scaffold a v1.4.1 project, you might need to use two different versions of Node: one of the generator and one for scaffolding the project.

Here's the test I run in Linux (WSL).

Test 00

cd spfx-test-00
sudo chown 1001:1001 .
docker run --rm -v $(pwd):/usr/app/spfx m365pnp/spfx:1.12.1 yo @microsoft/sharepoint --solution-name helloworld --component-type webpart --component-name hello-world-webpart --component-description "HelloWorld web part" --is-domain-isolated --framework none --environment spo --skip-feature-deployment false --skip-install
cd helloworld
docker run --rm -it -v $(pwd):/usr/app/spfx -p 4321:4321 -p 5432:5432 -p 35729:35729 m365pnp/spfx:1.4.1
npm install
chmod -R u=rwx,g=rx,o=rwx .
gulp trust-dev-cert

I get this:

Error: Your dev environment is running NodeJS version v8.9.4 which does not meet the requirements for running this tool. This tool requires a version of NodeJS that matches >=10.13.0

Test 01

cd spfx-test-01
sudo chown 1001:1001 .
docker run --rm -v $(pwd):/usr/app/spfx m365pnp/spfx:1.12.1 yo @microsoft/sharepoint --solution-name helloworld --component-type webpart --component-name hello-world-webpart --component-description "HelloWorld web part" --is-domain-isolated --framework none --environment spo --skip-feature-deployment false --skip-install

replace "skipFeatureDeployment": "false", with "skipFeatureDeployment": false,

modifying the ./config/serve.json file in your SharePoint Framework project to:

{
  "$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
  "port": 4321,
  "hostname": "0.0.0.0",
  "https": true,
  "initialPage": "https://localhost:5432/workbench",
  "api": {
    "port": 5432,
    "entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
  }
}
cd helloworld
docker run --rm -it -v $(pwd):/usr/app/spfx -p 4321:4321 -p 5432:5432 -p 35729:35729 m365pnp/spfx:1.12.1
npm install

Modify node_modules\@microsoft\spfx-heft-plugins\lib\plugins\webpackConfigurationPlugin\WebpackConfigurationGenerator.js:376

const debugBaseUrl = `${serveConfig.https ? 'https' : 'http'}://${serveConfig.hostname || 'localhost'}:${serveConfig.port || 4321}/dist/`;

to:

const debugBaseUrl = `${serveConfig.https ? 'https' : 'http'}://localhost:${serveConfig.port || 4321}/dist/`;
chmod -R u=rwx,g=rx,o=rwx .
gulp trust-dev-cert
gulp serve --nobrowser
$tcpClient = New-Object -TypeName System.Net.Sockets.TcpClient;
$tcpClient.Connect("localhost", 5432);
$tcpStream = $tcpClient.GetStream();
$callback = { param($sender, $cert, $chain, $errors) return $true };
$sslStream = New-Object -TypeName System.Net.Security.SslStream -ArgumentList @($tcpStream, $true, $callback);
$sslStream.AuthenticateAsClient('');
$certificate = $SslStream.RemoteCertificate;
$x509Certificate = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList $certificate
$store = new-object System.Security.Cryptography.X509Certificates.X509Store(
    [System.Security.Cryptography.X509Certificates.StoreName]::Root,
    "localmachine"
)
$store.open("MaxAllowed");
$store.add($x509Certificate);
$store.close();

Open https://localhost:5432/workbench in browser

image

Ctrl + C for stopping the web server

gulp bundle --ship

Output:

Build target: SHIP
[14:01:20] Using gulpfile /usr/app/spfx/gulpfile.js
[14:01:20] Starting 'bundle'...
[14:01:20] Starting gulp
[14:01:20] Starting subtask 'configure-sp-build-rig'...
[14:01:20] Finished subtask 'configure-sp-build-rig' after 2.24 ms
[14:01:20] Starting subtask 'pre-copy'...
[14:01:20] Finished subtask 'pre-copy' after 18 ms
[14:01:20] Starting subtask 'copy-static-assets'...
[14:01:20] Starting subtask 'sass'...
[14:01:20] Finished subtask 'copy-static-assets' after 25 ms
[14:01:20] Finished subtask 'sass' after 100 ms
[14:01:20] Starting subtask 'tslint'...
[14:01:20] [tslint] tslint version: 5.12.1
[14:01:20] Starting subtask 'tsc'...
[14:01:20] [tsc] typescript version: 3.7.7
[14:01:22] Finished subtask 'tsc' after 1.74 s
[14:01:22] Finished subtask 'tslint' after 2.12 s
[14:01:22] Starting subtask 'post-copy'...
[14:01:22] Finished subtask 'post-copy' after 120 μs
[14:01:22] Starting subtask 'configure-webpack'...
[14:01:22] Finished subtask 'configure-webpack' after 141 ms
[14:01:22] Starting subtask 'webpack'...
[14:01:23] Finished subtask 'webpack' after 657 ms
[14:01:23] Finished 'bundle' after 3.05 s
[14:01:23] ==================[ Finished ]==================
[14:01:24] Project helloworld version:0.0.1
[14:01:24] Build tools version:3.17.11
[14:01:24] Node version:v14.17.0
[14:01:24] Total duration:5.1 s

So, @lisaandsoftware, @waldekmastykarz can you think of any steps that I could take to replicate the issue of using 1.12.1 image?

It seems like in all cases you set the environment to spo, which means you get a project that uses SPFx v1.12.1. The problem is when you use the 1.12.1 generator to create an onprem project which will be using SPFx v1.4.1 and which requires an older version of node.

damn, you are right, my bad :)

Then I continue.

Test 02

cd spfx-test-02
sudo chown 1001:1001 .
docker run --rm -v $(pwd):/usr/app/spfx m365pnp/spfx:1.12.1 yo @microsoft/sharepoint --solution-name helloworld --component-type webpart --component-name hello-world-webpart --component-description "HelloWorld web part" --is-domain-isolated --framework none --environment onprem19 --skip-feature-deployment false --skip-install

replace "skipFeatureDeployment": "false" with "skipFeatureDeployment": false

cd helloworld
docker run --rm -it -v $(pwd):/usr/app/spfx -p 4321:4321 -p 5432:5432 -p 35729:35729 m365pnp/spfx:1.4.1
npm install
chmod -R u=rwx,g=rx,o=rwx .
gulp trust-dev-cert
gulp serve --nobrowser
$tcpClient = New-Object -TypeName System.Net.Sockets.TcpClient;
$tcpClient.Connect("localhost", 5432);
$tcpStream = $tcpClient.GetStream();
$callback = { param($sender, $cert, $chain, $errors) return $true };
$sslStream = New-Object -TypeName System.Net.Security.SslStream -ArgumentList @($tcpStream, $true, $callback);
$sslStream.AuthenticateAsClient('');
$certificate = $SslStream.RemoteCertificate;
$x509Certificate = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList $certificate
$store = new-object System.Security.Cryptography.X509Certificates.X509Store(
    [System.Security.Cryptography.X509Certificates.StoreName]::Root,
    "localmachine"
)
$store.open("MaxAllowed");
$store.add($x509Certificate);
$store.close();

Open https://localhost:5432/workbench in browser

Result: works as it should

Test 03

cd spfx-test-03
sudo chown 1001:1001 .
docker run --rm -v $(pwd):/usr/app/spfx m365pnp/spfx:1.12.1 yo @microsoft/sharepoint --solution-name helloworld --component-type webpart --component-name hello-world-webpart --component-description "HelloWorld web part" --is-domain-isolated --framework none --environment onprem19 --skip-feature-deployment false --skip-install
cd helloworld
cat <<EOF | sudo tee ./config/package-solution.json
{
  "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
  "solution": {
    "name": "helloworld-client-side-solution",
    "id": "87dc1601-9679-4485-b35f-46a79ed0bd1a",
    "version": "1.0.0.0",
    "includeClientSideAssets": true,
    "skipFeatureDeployment": false
  },
  "paths": {
    "zippedPackage": "solution/helloworld.sppkg"
  }
}
EOF
docker run --rm -it -v $(pwd):/usr/app/spfx -p 4321:4321 -p 5432:5432 -p 35729:35729 m365pnp/spfx:1.12.1
npm install
chmod -R u=rwx,g=rx,o=rwx .
gulp trust-dev-cert

Result:

ReferenceError: primordials is not defined
    at fs.js:45:5
    at req_ (/usr/app/spfx/node_modules/natives/index.js:143:24)
    at Object.req [as require] (/usr/app/spfx/node_modules/natives/index.js:55:10)
    at Object.<anonymous> (/usr/app/spfx/node_modules/vinyl-fs/node_modules/graceful-fs/fs.js:1:37)
    at Module._compile (internal/modules/cjs/loader.js:1068:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
    at Module.load (internal/modules/cjs/loader.js:933:32)
    at Function.Module._load (internal/modules/cjs/loader.js:774:14)
    at Module.require (internal/modules/cjs/loader.js:957:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (/usr/app/spfx/node_modules/vinyl-fs/node_modules/graceful-fs/graceful-fs.js:3:27)
    at Module._compile (internal/modules/cjs/loader.js:1068:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
    at Module.load (internal/modules/cjs/loader.js:933:32)
    at Function.Module._load (internal/modules/cjs/loader.js:774:14)
    at Module.require (internal/modules/cjs/loader.js:957:19)
About to exit with code: 1
Process terminated before summary could be written, possible error in async code not continuing!
Trying to exit with exit code 1

So yes, I guess the easiest is to label the v1.4.1 image as onprem.

I spent a lot of time trying to make it work too... I agree with your suggestion to label 1.4.1 as on prem. 👍

Before we do this feel free to use 1.4.1 tag like I did in the test 02 :)

docker run --rm -it -v $(pwd):/usr/app/spfx -p 4321:4321 -p 5432:5432 -p 35729:35729 m365pnp/spfx:1.4.1

I've updated the onprem tag, to point to v1.4.1