This is a Webpack plugin that simplifies the updating of your Visualforce page(s)/component(s) by embedding your static resource file(s) as script and link tags.
More about referencing static resource files in Visualforce markup here.
App.page
<apex:page>
<!--% styles %-->
<!--% styles %-->
<apex:pageBlock>
...
</apex:pageBlock>
...
<!--% scripts %-->
<!--% scripts %-->
</apex:page>
App.page
<apex:page>
<!--% styles %-->
<link type="text/css" rel="stylesheet" href="{!$Resource.dist, 'main.css')}" />
<!--% styles %-->
<apex:pageBlock>
...
</apex:pageBlock>
...
<!--% scripts %-->
<script type="text/javascript" src="{!$Resource.dist, 'bundle.js')}"></script>
<!--% scripts %-->
</apex:page>
npm i visualforce-template-webpack-plugin --save-dev
- Do not put anything between
<!--% scripts %--><!--% scripts %-->
comment tags. They will be erased!!
% scripts %
for your js files and % styles %
for your css files
<!--%scripts%-->
, <!--% scripts %-->
, or <!-- % scripts % -->
App.page
<apex:page>
<head>
<!--% styles %-->
<!-- WARNING: Do NOT Put anything [HERE]. Will get erased -->
<!--% styles %-->
</head>
<body>
<apex:form>
...
</apex:form>
<script>
//put non webpack/global javascript here
</script>
<!--% scripts %-->
<!-- WARNING: Do NOT Put anything [HERE]. Will get erased -->
<!--% scripts %-->
</body>
</apex:page>
webpack.config.js
const VisualforcePlugin = require('visualforce-template-webpack-plugin')
webpack.config.js
//From Step 1
const VisualforcePlugin = require('visualforce-template-webpack-plugin')
module.exports = {
entry: './index.js',
output: {
filname: '[name].bundle.js',
path: "./force-app/main/default/staticresources/dist"
},
plugins: [
// Add a new instance here
new VisualforcePlugin({
page: './force-app/default/main/pages/App.page'
})
]
}
Name | Type | Default | Required | Description |
---|---|---|---|---|
entry |
{String} or {Array} of strings |
main |
false |
Name of entry configuration key name. Needs to match your webpack config entry names. Defaults to all entrypoint assets if none specified. |
page |
{String} |
undefined |
true |
Relative path to your visualforce page or component file |
scriptHook |
{Function} |
undefined |
false | Callback function to modify src and other attributes on script tag |
styleHook |
{Function} |
undefined |
false | Function to hook into modifying attributes of link tags |
You can filter out entrypoint assets you wish to not include in the page.
Example: webpack.config.js
modules.exports = {
entry: {
app: './app.js',
main: './main.js',
mobile: './mobile.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, "force-app/main/default/staticresources/dist"),
},
plugins: [
new VisualforceTemplate({
entry: ['app', 'main'], // mobile entry is not included
page: path.resolve(__dirname, 'force-app/main/default/pages/App.page')
})
]
}
*You can optionally update a Visualforce Component as well*
Example: webpack.config.js
modules.exports = {
entry: './app.js',
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, "force-app/main/default/staticresources/dist"),
},
plugins: [
new VisualforceTemplate({
page: path.resolve(__dirname, 'force-app/main/default/components/[Name].component')
})
]
}
[Name].component
<apex:component>
<!--% scripts %-->
<script type="text/javascript" src="{!URLFOR($Resource.dist, 'main.bundle.js')}"></script>
<!--% scripts %-->
</apex:component>
Script Tag Attribute Defaults
Name | Default |
---|---|
type |
text/javascript |
src |
[Depends on output in static resource] |
async |
false |
defer |
false |
nomodule |
false |
How to overide defaults: Return an Object and setting any of the properties in the table above. Only need to include the script tag attributes you wish to change. The function is passed an object containing:
scriptHook: (scriptData) => {
const { resourceName, resourceFilePath } = scriptData;
// ...
return {
src: `${resourceName}/${resourceFilePath}`
}
}
new VisualforcePlugin({
entry: 'app',
page: path.resolve(__dirname, "./force-app/default/main/pages/App.page"),
scriptHook: ({ resourceName, resourceFilePath }) => {
// ...
return {
src: `{!URLFOR($Resource.${resourceName}, '${resourceFilePath}')}`,
type: 'text/javascript'
}
}
})
Style Tag Attribute Defaults
Name | Default |
---|---|
rel |
stylesheet |
href |
[Depends on output in static resource] |
type |
text/css |
How to overide defaults: Return an Object and setting any of the properties in the table above. Only need to include the script tag attributes you wish to change. The function is passed an object containing:
new VisualforcePlugin({
entry: 'app',
page: path.resolve(__dirname, "./force-app/default/main/pages/App.page"),
styleHook: ({ resourceName, resourceFilePath }) => {
return {
rel: 'stylesheet',
href: ``,
type: ''
};
}
})
webpack.config.js
const path = require('path')
const VisualforcePlugin = require('visualforce-template-webpack-plugin')
module.exports = {
entry: {
app: './index.js'
},
output: {
filename: 'bundle.js'
path: path.resolve(__dirname, "./force-app/main/default/staticresources/dist")
},
plugins: [
new VisualforcePlugin({
entry: 'app',
page: './force-app/default/main/pages/App.page'
})
]
}
App.page
<apex:page>
<apex:pageBlock>
...
</apex:pageBlock>
...
<!--% scripts %-->
<!--% scripts %-->
</apex:page>
App.page
<apex:page>
<apex:pageBlock>
...
</apex:pageBlock>
...
<!--% scripts %-->
<script type="text/javascript" src="{!$Resource.dist, 'bundle.js')}"></script>
<!--% scripts %-->
</apex:page>
example of updating more than one visualforce page/component w/ multiple entries
webpack.config.js
const path = require('path')
const VisualforcePlugin = require('visualforce-template-webpack-plugin')
module.exports = {
entry: {
app: './app.js',
admin: '/admin.js',
mobile: './admin.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, "./force-app/main/default/staticresources/dist")
},
plugins: [
new VisualforcePlugin([{
entry: 'app',
page: path.resolve(__dirname, "./force-app/main/default/pages/App.page")
},
{
entry: 'admin',
page: path.resolve(__dirname, "./force-app/main/default/pages/Admin.page")
},
{
entry: 'mobile',
page: path.resolve(__dirname, "./force-app/main/default/pages/AppSf1.page")
}])
]
}