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

feat(pv-scripts): webpack config update #232

Merged
merged 15 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/react-tsx/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
"global-require": 0,
"no-console": "off",
// note you must disable the base rule as it can report incorrect errors
"no-use-before-define": "off",
"no-use-before-define": "off"
},
"settings": {
"react": {
"version": "detect"
"version": "detect"
}
}
}
1 change: 0 additions & 1 deletion examples/react-tsx/pv.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module.exports = {
"namespace": "react-tsx-sample",
"jsEntry": "src/js/index.tsx",
"jsLegacyEntry": "src/js/legacyIndex.tsx",
"useReact": true,
"copyStaticFiles": true,
"cleanDest": true
Expand Down
4 changes: 0 additions & 4 deletions examples/react-tsx/src/js/legacyIndex.tsx

This file was deleted.

1 change: 0 additions & 1 deletion examples/react-tsx/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
<body>
<div id="main">Foo</div>
<script type="module" src="/js/react-tsx-sample.app.js"></script>
<script nomodule src="/js/react-tsx-sample.app.legacy.js"></script>
</body>

</html>
51 changes: 26 additions & 25 deletions packages/pv-scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ npm i @pro-vision/pv-scripts -D
## Usage

### Requirements
To use the CLI, you need to create at least the two entry-files (`jsEntry`, `jsLegacyEntry`), see [Basic Configuration](#basic-configuration).
To use the CLI, you need to create at least the entry-file (`jsEntry`), see [Basic Configuration](#basic-configuration).

### Command Line Interface

Expand All @@ -36,7 +36,7 @@ npx pv-scripts prod
#### CLI flags

##### `--stats` or `--statsJson`
Webpack build will use [webpack-bundle-analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer) to generate an html report or json output regarding the bundle sizes and its composition. Which will be stored under `target/report_module.html | target/report_legacy.html` and `target/report_module.json | target/report_legacy.json`.
Webpack build will use [webpack-bundle-analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer) to generate an html report or json output regarding the bundle sizes and its composition. Which will be stored under `target/report.html` and `target/report.json`.

This flag should only be used in combination with `prod` build to have a realistic information from the optimized bundles.

Expand All @@ -51,10 +51,8 @@ Basic Configuration can be done in a `pv.config.js` file in the npm project root
| devServerPort | number | 8616 | set `webpack-dev-server` port |
| srcPath | string | "src" | defines the working directory |
| destPath | string | "target" | defines where to put bundled files |
| namespace | string | "" | this controls the name-prefix on your bundled files following this pattern `[namespace].app.[?legacy].(js|css)` |
| namespace | string | "" | this controls the name-prefix on your bundled files following this pattern `[namespace].app.(js|css)` |
| jsEntry | string | "src/index.ts" | defines path of your (JS\|TS\|JSX\|TSX) entry file |
| jsLegacyEntry | string | "src/legacyIndex.ts" | defines path of your (JS\|TS\|JSX\|TSX) legacy entry file |
| disableLegacyBuild | boolean | false | disables legacy build |
| cssEntry | string | "src/index.scss" | defines path of your SCSS entry file. If `src/index.scss` does not exist, no error is thrown but the css generation is simply skipped|
| useTS | boolean | true | defines whether you want to use Typescript |
| useReact | boolean | false | defines whether you want to use React |
Expand All @@ -67,15 +65,16 @@ Basic Configuration can be done in a `pv.config.js` file in the npm project root
| resourcesSrc | string | "resources" | defines resources folder which is copied to target/resources |
| autoConsoleClear | boolean | false | defines whether the console should be cleared automatically in dev-mode |
| enableContentHash | boolean | false | defines whether generated js and css files should contain a content hash in their names |
##### Example:
| babelDecorator | string | "legacy" | @babel/plugin-proposal-decorators' `version` property |

##### Example

```js
// pv.config.js
module.exports = {
devServerPort: 8616,
destPath: "target",
jsEntry: "src/index.js",
jsLegacyEntry: "src/legacyIndex.js",
cssEntry: "src/index.scss",
useTS: false,
useReact: false,
Expand All @@ -90,37 +89,39 @@ For further customization of the webpack-config, specific config-files can be ad
**webpack.config.js:**
Valid webpack.config file which will be merged with both (dev/prod) default configs.

**webpack.config.module.js:**
Valid webpack.config file which will be merged with the module build of both (dev/prod) default configs.

**webpack.config.legacy.js:**
Valid webpack.config file which will be merged with the legacy build of both (dev/prod) default configs.

**webpack.config.dev.js:**
Valid webpack.config file which will be merged with the dev default config.

**webpack.config.dev.module.js:**
Valid webpack.config file which will be merged with the module build of the dev default config.

**webpack.config.dev.legacy.js:**
Valid webpack.config file which will be merged with the legacy build of the dev default config.

**webpack.config.prod.js:**
Valid webpack.config file which will be merged with the prod default config.

**webpack.config.prod.module.js:**
Valid webpack.config file which will be merged with the module build of the prod default config.
**.babelrc.json**
Will add additional babel plugins to the existing [webpack config](https://github.com/pro-vision/fe-tools/tree/master/packages/pv-scripts/webpack/base/tasks/compileJS.js)

#### SVG loading

**webpack.config.prod.legacy.js:**
Valid webpack.config file which will be merged with the legacy build of the prod default config.
svg files will be automatically loaded when imported/referenced by js/ts/scss files.

Default behavior would be to extract the svg content when requested from js (this would allow to use the svg content easily to render markup), for css the svg will be emitted as a .svg file to the target folder and its url used in the output css. These can be overwritten by webpacks resource queries:

| query | behavior | example |
|-------|----------|---------|
| `resource` or `external` | resource will be emitted to target folder and its url added to the import | `import svgUrl from("./icon.svg?resource"); fetch(svgUrl);` |
| `inline` | svg content will be base64 encoded an used inline | `background-image: url("./img.svg?inline"); // => background-image: url(data:image/svg+xml;base64,PHN...` |
| `auto` | webpack will automatically choose between `resource` and `inline` based on the file size see [webpack's documentation](https://webpack.js.org/guides/asset-modules/). | |
| `source` or `raw` | the svg files content will be used | `import svgContent from("./icon.svg?raw"); el.innerHTML = svgContent;` |
| `/*! webpackIgnore: true */` | will ignore the file/url | `/* webpackIgnore: true */ background-image: url("http//some-url.svg");` |

#### SASS compilation

Per default the new (dart-)`sass` package will be installed and used. You can also install the `sass-embedded` package as an npm dependency which will then be automatically used and is twice as fast as the default sass. If you need to use the legacy [sass syntax](https://sass-lang.com/documentation/breaking-changes/) (e.g. `/` instead of `math.div`) then you need to install `node-sass` as an npm dependency, and it will automatically be used when sass code is compiled.

#### Browserslist

A default browser query is used for compiling javascript and css. i.e. IE11 for the "legacy" bundle and latest 2 versions of evergreen browsers (chrome, firefox, safari, edge) for the "modern" bundle. And all combined for the css output. You can define your own [browserslist](https://github.com/browserslist/browserslist) to override any of these target groups. Don't forget to define default browsers, browser for `[modern]` or `[legacy]` environment. See default [.browserslistrc](https://github.com/pro-vision/fe-tools/tree/master/packages/pv-scripts/config/.browserslistrc) file for an example.
A default browser query is used for compiling javascript and css. i.e. latest 2 versions of evergreen browsers (chrome, firefox, safari, edge). You can define your own [browserslist](https://github.com/browserslist/browserslist). See default [.browserslistrc](https://github.com/pro-vision/fe-tools/tree/master/packages/pv-scripts/config/.browserslistrc) file for an example.

## Examples

You can find example projects in the `examples` folder:

* React with TypeScript: [react-tsx](https://github.com/pro-vision/fe-tools/tree/master/examples/react-tsx)

17 changes: 1 addition & 16 deletions packages/pv-scripts/config/.browserslistrc
Original file line number Diff line number Diff line change
@@ -1,24 +1,9 @@
# pv-scripts default target browsers,
# will be overridden with project browserslist
# can be overridden with project's browserslist

# default, (modern+legacy) used for PostCSS
last 2 firefox versions
last 2 chrome versions
last 2 and_chr versions
last 2 safari versions
last 2 ios_saf versions
last 2 edge versions
IE >= 11

# will be used for modern bundle
[modern]
last 2 firefox versions
last 2 chrome versions
last 2 and_chr versions
last 2 safari versions
last 2 ios_saf versions
last 2 edge versions

# will be used for legacy bundle
[legacy]
IE >= 11
3 changes: 1 addition & 2 deletions packages/pv-scripts/config/default.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ module.exports = {
destPath: "target",
namespace: "",
jsEntry: "src/index.ts",
jsLegacyEntry: "src/legacyIndex.ts",
disableLegacyBuild: false,
cssEntry: "src/index.scss",
useTS: true,
useReact: false,
Expand All @@ -17,4 +15,5 @@ module.exports = {
autoConsoleClear: false,
handlebarsLoaderOptions: {},
enableContentHash: false,
babelDecorator: "legacy", // babel-plugin-proposal-decorators' `version` property
};
5 changes: 0 additions & 5 deletions packages/pv-scripts/helpers/buildConfigHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,6 @@ const getHandlebarsLoaderOptions = () => {
return handlebarsLoaderOptions;
};

const legacyBuildDisabled = () => {
return getBuildConfig().disableLegacyBuild;
};

module.exports = {
getBuildConfig,
getJSExtName,
Expand All @@ -103,6 +99,5 @@ module.exports = {
shouldAddCssEntry,
shouldUseHtmlCompiler,
getHandlebarsLoaderOptions,
legacyBuildDisabled,
shouldAddContentHash,
};
19 changes: 0 additions & 19 deletions packages/pv-scripts/helpers/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,6 @@ const jsEntry = () => {
return resolveApp(config.jsEntry.replace(extname, getJSExtName(config)));
};

const jsLegacyEntry = () => {
if (config.jsLegacyEntry !== defaultConfig.jsLegacyEntry) {
return resolveApp(config.jsLegacyEntry);
}

const extname = path.extname(config.jsLegacyEntry);

const jsLegacyEntryPath = resolveApp(
config.jsLegacyEntry.replace(extname, getJSExtName(config))
);

const jsLegacyEntryExists = existsSync(jsLegacyEntryPath);

if (jsLegacyEntryExists) return jsLegacyEntryPath;

return jsEntry();
};

const cssEntry = resolveApp(config.cssEntry);
const appTarget = resolveApp(config.destPath);

Expand All @@ -75,7 +57,6 @@ module.exports = {
appPath,
appSrc,
jsEntry,
jsLegacyEntry,
cssEntry,
appTarget,
join,
Expand Down
35 changes: 3 additions & 32 deletions packages/pv-scripts/helpers/prepareWebpackConfig.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,24 @@
const { merge } = require("webpack-merge");

const { getCustomWebpackConfig } = require("../helpers/webpackConfigHelpers");
const { legacyBuildDisabled } = require("../helpers/buildConfigHelpers");
const { getConfig } = require("../webpack/getConfig");

async function prepareWebpackConfig(mode) {
const customModeConfigName =
mode === "development" ? "webpack.config.dev" : "webpack.config.prod";
const customWebpackConfig = await getCustomWebpackConfig("webpack.config.js");
const customWebpackModuleConfig = await getCustomWebpackConfig(
"webpack.config.module.js"
);
const customWebpackLegacyConfig = await getCustomWebpackConfig(
"webpack.config.legacy.js"
);
const customWebpackModeConfig = await getCustomWebpackConfig(
`${customModeConfigName}.js`
);
const customWebpackModeModuleConfig = await getCustomWebpackConfig(
`${customModeConfigName}.module.js`
);
const customWebpackModeLegacyConfig = await getCustomWebpackConfig(
`${customModeConfigName}.legacy.js`
);

const customModuleConfig = merge(
customWebpackConfig,
customWebpackModuleConfig,
customWebpackModeConfig,
customWebpackModeModuleConfig
customWebpackModeConfig
);

const customLegacyConfig = merge(
customWebpackConfig,
customWebpackLegacyConfig,
customWebpackModeConfig,
customWebpackModeLegacyConfig
);

const [defaultModuleConfig, defaultLegacyConfig] = getConfig(mode);

if (legacyBuildDisabled()) {
return merge(defaultModuleConfig, customModuleConfig);
}
const defaultModuleConfig = getConfig(mode);

return [
merge(defaultModuleConfig, customModuleConfig),
merge(defaultLegacyConfig, customLegacyConfig),
];
return merge(defaultModuleConfig, customModuleConfig);
}

module.exports = {
Expand Down
14 changes: 14 additions & 0 deletions packages/pv-scripts/helpers/webpackConfigHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ const getCustomWebpackConfig = (configName) => {
});
};

function getBuildDependencies() {
return [
"./pv.config.js",
"./webpack.config.js",
"./webpack.config.dev.js",
"./.browserslistrc",
"./.babelrc.json",
"./postcss.config.js",
]
.map((configFile) => resolveApp(configFile))
.filter((filePath) => existsSync(filePath));
}

module.exports = {
getCustomWebpackConfig,
getBuildDependencies,
};
Loading
Loading